85
85
86
86
** 方法一:BFS**
87
87
88
+ 本题数据规模较小,我们可以使用 BFS 暴力搜索所有可能的状态,然后取字典序最小的状态即可。
89
+
90
+ ** 方法二:枚举**
91
+
92
+ 我们观察发现,对于累加操作,数字最多累加 $10$ 次,就会回到原来的状态;对于轮转操作,字符串最多轮转 $n$ 次,也会回到原来的状态。
93
+
94
+ 因此,轮转操作最多产生 $n$ 种状态,如果轮转位数 $b$ 为偶数,累加操作只会对奇数位数字产生影响,因此总共产生 $n \times 10$ 种状态;如果轮转位数 $b$ 为奇数,累加操作既会对奇数位数字产生影响,也会对偶数位数字产生影响,因此总共产生 $n \times 10 \times 10$ 种状态。
95
+
96
+ 所以,我们直接枚举所有的字符串状态,取字典序最小的状态即可。
97
+
98
+ 时间复杂度 $O(n^2 \times 10^2)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $s$ 的长度。
99
+
88
100
<!-- tabs:start -->
89
101
90
102
### ** Python3**
@@ -99,16 +111,39 @@ class Solution:
99
111
ans = s
100
112
while q:
101
113
s = q.popleft()
102
- if s < ans :
114
+ if ans > s :
103
115
ans = s
104
- nxt1 = ' ' .join(
105
- [str ((int (c) + a) % 10 ) if i & 1 else c for i, c in enumerate (s)]
106
- )
107
- nxt2 = s[- b:] + s[:- b]
108
- for nxt in (nxt1, nxt2):
109
- if nxt not in vis:
110
- vis.add(nxt)
111
- q.append(nxt)
116
+ t1 = ' ' .join([str ((int (c) + a) % 10 ) if i & 1 else c for i, c in enumerate (s)])
117
+ t2 = s[- b:] + s[:- b]
118
+ for t in (t1, t2):
119
+ if t not in vis:
120
+ vis.add(t)
121
+ q.append(t)
122
+ return ans
123
+ ```
124
+
125
+ ``` python
126
+ class Solution :
127
+ def findLexSmallestString (self , s : str , a : int , b : int ) -> str :
128
+ ans = s
129
+ n = len (s)
130
+ s = list (s)
131
+ for _ in range (n):
132
+ s = s[- b:] + s[:- b]
133
+ for j in range (10 ):
134
+ for k in range (1 , n, 2 ):
135
+ s[k] = str ((int (s[k]) + a) % 10 )
136
+ if b & 1 :
137
+ for p in range (10 ):
138
+ for k in range (0 , n, 2 ):
139
+ s[k] = str ((int (s[k]) + a) % 10 )
140
+ t = ' ' .join(s)
141
+ if ans > t:
142
+ ans = t
143
+ else :
144
+ t = ' ' .join(s)
145
+ if ans > t:
146
+ ans = t
112
147
return ans
113
148
```
114
149
@@ -119,26 +154,61 @@ class Solution:
119
154
``` java
120
155
class Solution {
121
156
public String findLexSmallestString (String s , int a , int b ) {
122
- Queue <String > q = new ArrayDeque<> ();
157
+ Deque <String > q = new ArrayDeque<> ();
123
158
q. offer(s);
124
159
Set<String > vis = new HashSet<> ();
125
160
vis. add(s);
126
161
String ans = s;
162
+ int n = s. length();
127
163
while (! q. isEmpty()) {
128
164
s = q. poll();
129
- if (s . compareTo(ans) < 0 ) {
165
+ if (ans . compareTo(s) > 0 ) {
130
166
ans = s;
131
167
}
132
168
char [] cs = s. toCharArray();
133
- for (int i = 1 ; i < cs . length ; i += 2 ) {
169
+ for (int i = 1 ; i < n ; i += 2 ) {
134
170
cs[i] = (char ) (((cs[i] - ' 0' + a) % 10 ) + ' 0' );
135
171
}
136
- String nxt1 = String . valueOf(cs);
137
- String nxt2 = s. substring(b) + s. substring(0 , b);
138
- for (String nxt : new String [] {nxt1, nxt2}) {
139
- if (! vis. contains(nxt)) {
140
- vis. add(nxt);
141
- q. offer(nxt);
172
+ String t1 = String . valueOf(cs);
173
+ String t2 = s. substring(b) + s. substring(0 , b);
174
+ for (String t : List . of(t1, t2)) {
175
+ if (vis. add(t)) {
176
+ q. offer(t);
177
+ }
178
+ }
179
+ }
180
+ return ans;
181
+ }
182
+ }
183
+ ```
184
+
185
+ ``` java
186
+ class Solution {
187
+ public String findLexSmallestString (String s , int a , int b ) {
188
+ int n = s. length();
189
+ String ans = s;
190
+ for (int i = 0 ; i < n; ++ i) {
191
+ s = s. substring(b) + s. substring(0 , b);
192
+ char [] cs = s. toCharArray();
193
+ for (int j = 0 ; j < 10 ; ++ j) {
194
+ for (int k = 1 ; k < n; k += 2 ) {
195
+ cs[k] = (char ) (((cs[k] - ' 0' + a) % 10 ) + ' 0' );
196
+ }
197
+ if ((b & 1 ) == 1 ) {
198
+ for (int p = 0 ; p < 10 ; ++ p) {
199
+ for (int k = 0 ; k < n; k += 2 ) {
200
+ cs[k] = (char ) (((cs[k] - ' 0' + a) % 10 ) + ' 0' );
201
+ }
202
+ s = String . valueOf(cs);
203
+ if (ans. compareTo(s) > 0 ) {
204
+ ans = s;
205
+ }
206
+ }
207
+ } else {
208
+ s = String . valueOf(cs);
209
+ if (ans. compareTo(s) > 0 ) {
210
+ ans = s;
211
+ }
142
212
}
143
213
}
144
214
}
@@ -153,21 +223,52 @@ class Solution {
153
223
class Solution {
154
224
public:
155
225
string findLexSmallestString(string s, int a, int b) {
156
- unordered_set <string > vis {{s}};
157
- queue <string > q {{s}};
226
+ queue <string > q {{s}};
227
+ unordered_set <string > vis {{s}};
158
228
string ans = s;
159
229
int n = s.size();
160
230
while (!q.empty()) {
161
231
s = q.front();
162
232
q.pop();
163
- if (s < ans) ans = s;
164
- string nxt1 = s;
165
- for (int i = 1; i < n; i += 2) nxt1[ i] = ((nxt1[ i] - '0' + a) % 10) + '0';
166
- string nxt2 = s.substr(n - b) + s.substr(0, n - b);
167
- for (string nxt : {nxt1, nxt2}) {
168
- if (!vis.count(nxt)) {
169
- vis.insert(nxt);
170
- q.push(nxt);
233
+ ans = min(ans, s);
234
+ string t1 = s;
235
+ for (int i = 1; i < n; i += 2) {
236
+ t1[ i] = (t1[ i] - '0' + a) % 10 + '0';
237
+ }
238
+ string t2 = s.substr(n - b) + s.substr(0, n - b);
239
+ for (auto& t : {t1, t2}) {
240
+ if (!vis.count(t)) {
241
+ vis.insert(t);
242
+ q.emplace(t);
243
+ }
244
+ }
245
+ }
246
+ return ans;
247
+ }
248
+ };
249
+ ```
250
+
251
+ ```cpp
252
+ class Solution {
253
+ public:
254
+ string findLexSmallestString(string s, int a, int b) {
255
+ int n = s.size();
256
+ string ans = s;
257
+ for (int i = 0; i < n; ++i) {
258
+ s = s.substr(n - b) + s.substr(0, n - b);
259
+ for (int j = 0; j < 10; ++j) {
260
+ for (int k = 1; k < n; k += 2) {
261
+ s[k] = (s[k] - '0' + a) % 10 + '0';
262
+ }
263
+ if (b & 1) {
264
+ for (int p = 0; p < 10; ++p) {
265
+ for (int k = 0; k < n; k += 2) {
266
+ s[k] = (s[k] - '0' + a) % 10 + '0';
267
+ }
268
+ ans = min(ans, s);
269
+ }
270
+ } else {
271
+ ans = min(ans, s);
171
272
}
172
273
}
173
274
}
@@ -183,32 +284,59 @@ func findLexSmallestString(s string, a int, b int) string {
183
284
q := []string {s}
184
285
vis := map [string ]bool {s: true }
185
286
ans := s
287
+ n := len (s)
186
288
for len (q) > 0 {
187
289
s = q[0 ]
188
290
q = q[1 :]
189
- if s < ans {
291
+ if ans > s {
190
292
ans = s
191
293
}
192
- for _, nxt := range []string{op1(s, a), op2(s, b)} {
193
- if !vis[nxt] {
194
- vis[nxt] = true
195
- q = append(q, nxt)
294
+ t1 := []byte (s)
295
+ for i := 1 ; i < n; i += 2 {
296
+ t1[i] = byte ((int (t1[i]-' 0' )+a)%10 + ' 0' )
297
+ }
298
+ t2 := s[n-b:] + s[:n-b]
299
+ for _ , t := range []string {string (t1), t2} {
300
+ if !vis[t] {
301
+ vis[t] = true
302
+ q = append (q, t)
196
303
}
197
304
}
198
305
}
199
306
return ans
200
307
}
308
+ ```
201
309
202
- func op1(s string, a int) string {
203
- res := []byte(s)
204
- for i := 1; i < len(s); i += 2 {
205
- res[i] = byte((int(res[i]-'0')+a)%10 + '0')
310
+ ``` go
311
+ func findLexSmallestString (s string , a int , b int ) string {
312
+ n := len (s)
313
+ ans := s
314
+ for _ = range s {
315
+ s = s[n-b:] + s[:n-b]
316
+ cs := []byte (s)
317
+ for j := 0 ; j < 10 ; j++ {
318
+ for k := 1 ; k < n; k += 2 {
319
+ cs[k] = byte ((int (cs[k]-' 0' )+a)%10 + ' 0' )
320
+ }
321
+ if b&1 == 1 {
322
+ for p := 0 ; p < 10 ; p++ {
323
+ for k := 0 ; k < n; k += 2 {
324
+ cs[k] = byte ((int (cs[k]-' 0' )+a)%10 + ' 0' )
325
+ }
326
+ s = string (cs)
327
+ if ans > s {
328
+ ans = s
329
+ }
330
+ }
331
+ } else {
332
+ s = string (cs)
333
+ if ans > s {
334
+ ans = s
335
+ }
336
+ }
337
+ }
206
338
}
207
- return string(res)
208
- }
209
-
210
- func op2(s string, b int) string {
211
- return s[len(s)-b:] + s[:len(s)-b]
339
+ return ans
212
340
}
213
341
```
214
342
0 commit comments