65
65
66
66
## 解法
67
67
68
- ### 方法一
68
+ ### 方法一:枚举
69
+
70
+ 我们不妨假设,如果只操作一次,就能使得 ` word ` 恢复到初始状态,那么意味着 ` word[k:] ` 是 ` word ` 的前缀,即 ` word[k:] == word[:n-k] ` 。
71
+
72
+ 如果有多次操作,不妨设 $i$ 为操作次数,那么意味着 ` word[k*i:] ` 是 ` word ` 的前缀,即 ` word[k*i:] == word[:n-k*i] ` 。
73
+
74
+ 因此,我们可以枚举操作次数,判断 ` word[k*i:] ` 是否是 ` word ` 的前缀,如果是,则返回 $i$。
75
+
76
+ 时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为 ` word ` 的长度。
69
77
70
78
<!-- tabs:start -->
71
79
72
80
``` python
73
81
class Solution :
74
82
def minimumTimeToInitialState (self , word : str , k : int ) -> int :
75
83
n = len (word)
76
- for i in range (1 , 10001 ):
77
- re = i * k
78
- if re >= n:
79
- return i
80
- if word[re:] == word[:n - re]:
81
- return i
82
- return 0
83
-
84
+ for i in range (k, n, k):
85
+ if word[i:] == word[:- i]:
86
+ return i // k
87
+ return (n + k - 1 ) // k
84
88
```
85
89
86
90
``` java
87
91
class Solution {
88
92
public int minimumTimeToInitialState (String word , int k ) {
89
93
int n = word. length();
90
- for (int i = 1 ; i <= 10000 ; i++ ) {
91
- int re = i * k;
92
- if (re >= n) {
93
- return i;
94
- }
95
- String str = word. substring(re);
96
- boolean flag = true ;
97
- for (int j = 0 ; j < str. length(); j++ ) {
98
- if (str. charAt(j) != word. charAt(j)) {
99
- flag = false ;
100
- break ;
101
- }
102
- }
103
- if (flag) {
104
- return i;
94
+ for (int i = k; i < n; i += k) {
95
+ if (word. substring(i). equals(word. substring(0 , n - i))) {
96
+ return i / k;
105
97
}
106
98
}
107
- return 0 ;
99
+ return (n + k - 1 ) / k ;
108
100
}
109
101
}
110
102
```
@@ -113,74 +105,186 @@ class Solution {
113
105
class Solution {
114
106
public:
115
107
int minimumTimeToInitialState(string word, int k) {
116
- int n = word.length();
117
- for (int i = 1; i <= 10000; i++) {
118
- int re = i * k;
119
- if (re >= n) {
120
- return i;
121
- }
122
- string str = word.substr(re);
123
- bool flag = true;
124
- for (int j = 0; j < str.length(); j++) {
125
- if (str[ j] != word[ j] ) {
126
- flag = false;
127
- break;
128
- }
129
- }
130
- if (flag) {
131
- return i;
108
+ int n = word.size();
109
+ for (int i = k; i < n; i += k) {
110
+ if (word.substr(i) == word.substr(0, n - i)) {
111
+ return i / k;
132
112
}
133
113
}
134
- return 0 ;
114
+ return (n + k - 1) / k ;
135
115
}
136
116
};
137
117
```
138
118
139
119
```go
140
120
func minimumTimeToInitialState(word string, k int) int {
141
121
n := len(word)
142
- for i := 1; i <= 10000; i++ {
143
- re := i * k
144
- if re >= n {
145
- return i
146
- }
147
- str := word[re:]
148
- flag := true
149
- for j := 0; j < len(str); j++ {
150
- if str[j] != word[j] {
151
- flag = false
152
- break
153
- }
154
- }
155
- if flag {
156
- return i
122
+ for i := k; i < n; i += k {
123
+ if word[i:] == word[:n-i] {
124
+ return i / k
157
125
}
158
126
}
159
- return 0
127
+ return (n + k - 1) / k
160
128
}
161
129
```
162
130
163
131
``` ts
164
132
function minimumTimeToInitialState(word : string , k : number ): number {
165
133
const n = word .length ;
166
- for (let i = 1 ; i <= 10000 ; i ++ ) {
167
- const re = i * k ;
168
- if (re >= n ) {
169
- return i ;
134
+ for (let i = k ; i < n ; i += k ) {
135
+ if (word .slice (i ) === word .slice (0 , - i )) {
136
+ return Math .floor (i / k );
170
137
}
171
- const str = word .substring (re );
172
- let flag = true ;
173
- for (let j = 0 ; j < str .length ; j ++ ) {
174
- if (str [j ] !== word [j ]) {
175
- flag = false ;
176
- break ;
138
+ }
139
+ return Math .floor ((n + k - 1 ) / k );
140
+ }
141
+ ```
142
+
143
+ <!-- tabs: end -->
144
+
145
+ ### 方法二:枚举 + 字符串哈希
146
+
147
+ 我们也可以在方法一的基础上,利用字符串哈希来判断两个字符串是否相等。
148
+
149
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为 ` word ` 的长度。
150
+
151
+ <!-- tabs: start -->
152
+
153
+ ``` python
154
+ class Hashing :
155
+ __slots__ = [" mod" , " h" , " p" ]
156
+
157
+ def __init__ (self , s : str , base : int , mod : int ):
158
+ self .mod = mod
159
+ self .h = [0 ] * (len (s) + 1 )
160
+ self .p = [1 ] * (len (s) + 1 )
161
+ for i in range (1 , len (s) + 1 ):
162
+ self .h[i] = (self .h[i - 1 ] * base + ord (s[i - 1 ])) % mod
163
+ self .p[i] = (self .p[i - 1 ] * base) % mod
164
+
165
+ def query (self , l : int , r : int ) -> int :
166
+ return (self .h[r] - self .h[l - 1 ] * self .p[r - l + 1 ]) % self .mod
167
+
168
+
169
+ class Solution :
170
+ def minimumTimeToInitialState (self , word : str , k : int ) -> int :
171
+ hashing = Hashing(word, 13331 , 998244353 )
172
+ n = len (word)
173
+ for i in range (k, n, k):
174
+ if hashing.query(1 , n - i) == hashing.query(i + 1 , n):
175
+ return i // k
176
+ return (n + k - 1 ) // k
177
+ ```
178
+
179
+ ``` java
180
+ class Hashing {
181
+ private final long [] p;
182
+ private final long [] h;
183
+ private final long mod;
184
+
185
+ public Hashing (String word , long base , int mod ) {
186
+ int n = word. length();
187
+ p = new long [n + 1 ];
188
+ h = new long [n + 1 ];
189
+ p[0 ] = 1 ;
190
+ this . mod = mod;
191
+ for (int i = 1 ; i <= n; i++ ) {
192
+ p[i] = p[i - 1 ] * base % mod;
193
+ h[i] = (h[i - 1 ] * base + word. charAt(i - 1 ) - ' a' ) % mod;
194
+ }
195
+ }
196
+
197
+ public long query (int l , int r ) {
198
+ return (h[r] - h[l - 1 ] * p[r - l + 1 ] % mod + mod) % mod;
199
+ }
200
+ }
201
+
202
+ class Solution {
203
+ public int minimumTimeToInitialState (String word , int k ) {
204
+ Hashing hashing = new Hashing (word, 13331 , 998244353 );
205
+ int n = word. length();
206
+ for (int i = k; i < n; i += k) {
207
+ if (hashing. query(1 , n - i) == hashing. query(i + 1 , n)) {
208
+ return i / k;
177
209
}
178
210
}
179
- if (flag ) {
180
- return i ;
211
+ return (n + k - 1 ) / k;
212
+ }
213
+ }
214
+ ```
215
+
216
+ ``` cpp
217
+ class Hashing {
218
+ private:
219
+ vector<long long > p;
220
+ vector<long long > h;
221
+ long long mod;
222
+
223
+ public:
224
+ Hashing(string word, long long base, int mod) {
225
+ int n = word.size();
226
+ p.resize(n + 1);
227
+ h.resize(n + 1);
228
+ p[ 0] = 1;
229
+ this->mod = mod;
230
+ for (int i = 1; i <= n; i++) {
231
+ p[ i] = (p[ i - 1] * base) % mod;
232
+ h[ i] = (h[ i - 1] * base + word[ i - 1] - 'a') % mod;
181
233
}
182
234
}
183
- return 0 ;
235
+
236
+ long long query(int l, int r) {
237
+ return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
238
+ }
239
+ };
240
+
241
+ class Solution {
242
+ public:
243
+ int minimumTimeToInitialState(string word, int k) {
244
+ Hashing hashing(word, 13331, 998244353);
245
+ int n = word.size();
246
+ for (int i = k; i < n; i += k) {
247
+ if (hashing.query(1, n - i) == hashing.query(i + 1, n)) {
248
+ return i / k;
249
+ }
250
+ }
251
+ return (n + k - 1) / k;
252
+ }
253
+ };
254
+ ```
255
+
256
+ ```go
257
+ type Hashing struct {
258
+ p []int64
259
+ h []int64
260
+ mod int64
261
+ }
262
+
263
+ func NewHashing(word string, base int64, mod int64) *Hashing {
264
+ n := len(word)
265
+ p := make([]int64, n+1)
266
+ h := make([]int64, n+1)
267
+ p[0] = 1
268
+ for i := 1; i <= n; i++ {
269
+ p[i] = (p[i-1] * base) % mod
270
+ h[i] = (h[i-1]*base + int64(word[i-1]-'a')) % mod
271
+ }
272
+ return &Hashing{p, h, mod}
273
+ }
274
+
275
+ func (hashing *Hashing) Query(l, r int) int64 {
276
+ return (hashing.h[r] - hashing.h[l-1]*hashing.p[r-l+1]%hashing.mod + hashing.mod) % hashing.mod
277
+ }
278
+
279
+ func minimumTimeToInitialState(word string, k int) int {
280
+ hashing := NewHashing(word, 13331, 998244353)
281
+ n := len(word)
282
+ for i := k; i < n; i += k {
283
+ if hashing.Query(1, n-i) == hashing.Query(i+1, n) {
284
+ return i / k
285
+ }
286
+ }
287
+ return (n + k - 1) / k
184
288
}
185
289
```
186
290
0 commit comments