问题:
给定一个由0~9构成的字符串s
对其有两种操作:
- 偶数位置+a(超过9,则从0开始循环)
- 例:if
s = "3456"
anda = 5
,s
becomes"3951"
.
- 例:if
- 字符串向后移动 b位(后面的字符循环到字符串前部)
- 例:if
s = "3456"
andb = 1
,s
becomes"6345"
.
- 例:if
求进行多次操作后,能获得的数值最小的字符串是什么。
Example 1: Input: s = "5525", a = 9, b = 2 Output: "2050" Explanation: We can apply the following operations: Start: "5525" Rotate: "2555" Add: "2454" Add: "2353" Rotate: "5323" Add: "5222" Add: "5121" Rotate: "2151" Add: "2050" There is no way to obtain a string that is lexicographically smaller then "2050". Example 2: Input: s = "74", a = 5, b = 1 Output: "24" Explanation: We can apply the following operations: Start: "74" Rotate: "47" Add: "42" Rotate: "24" There is no way to obtain a string that is lexicographically smaller then "24". Example 3: Input: s = "0011", a = 4, b = 2 Output: "0011" Explanation: There are no sequence of operations that will give us a lexicographically smaller string than "0011". Example 4: Input: s = "43987654", a = 7, b = 3 Output: "00553311" Constraints: 2 <= s.length <= 100 s.length is even. s consists of digits from 0 to 9 only. 1 <= a <= 9 1 <= b <= s.length - 1
解法:BFS
本题的操作会出现字符串循环出现。
- 状态:
- 字符串s,
- visited标记已经访问过的字符串。
- 选择:
- add
- rotate
对于每次出队字符串cur,和结果res取最小
最终遍历完成,得到res,即为最小。
代码参考:
1 class Solution { 2 public: 3 int n; 4 string add(string s, int a) { 5 for(int i=1; i<n; i+=2) { 6 s[i] = ((s[i]-'0'+a)%10) + '0'; 7 } 8 return s; 9 } 10 string rotate(string s, int b) { 11 string s_back = s.substr(n-b); 12 string s_front = s.substr(0,n-b); 13 return s_back+s_front; 14 } 15 string findLexSmallestString(string s, int a, int b) { 16 n = s.length(); 17 string res = s; 18 queue<string> q; 19 unordered_set<string> visited; 20 q.push(s); 21 while(!q.empty()) { 22 string cur = q.front(); 23 q.pop(); 24 res = min(res, cur); 25 string adds = add(cur, a); 26 string rtts = rotate(cur, b); 27 if(visited.insert(adds).second) { 28 q.push(adds); 29 } 30 if(visited.insert(rtts).second) { 31 q.push(rtts); 32 } 33 } 34 return res; 35 } 36 };