Skip to content

Commit 1d97527

Browse files
authored
feat: add solutions to lc problem: No.3029 (#2319)
No.3029.Minimum Time to Revert Word to Initial State I
1 parent 9236629 commit 1d97527

File tree

16 files changed

+692
-391
lines changed

16 files changed

+692
-391
lines changed

solution/3000-3099/3029.Minimum Time to Revert Word to Initial State I/README.md

+175-71
Original file line numberDiff line numberDiff line change
@@ -65,46 +65,38 @@
6565

6666
## 解法
6767

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` 的长度。
6977

7078
<!-- tabs:start -->
7179

7280
```python
7381
class Solution:
7482
def minimumTimeToInitialState(self, word: str, k: int) -> int:
7583
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
8488
```
8589

8690
```java
8791
class Solution {
8892
public int minimumTimeToInitialState(String word, int k) {
8993
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;
10597
}
10698
}
107-
return 0;
99+
return (n + k - 1) / k;
108100
}
109101
}
110102
```
@@ -113,74 +105,186 @@ class Solution {
113105
class Solution {
114106
public:
115107
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;
132112
}
133113
}
134-
return 0;
114+
return (n + k - 1) / k;
135115
}
136116
};
137117
```
138118
139119
```go
140120
func minimumTimeToInitialState(word string, k int) int {
141121
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
157125
}
158126
}
159-
return 0
127+
return (n + k - 1) / k
160128
}
161129
```
162130

163131
```ts
164132
function minimumTimeToInitialState(word: string, k: number): number {
165133
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);
170137
}
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;
177209
}
178210
}
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;
181233
}
182234
}
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
184288
}
185289
```
186290

0 commit comments

Comments
 (0)