Skip to content

Commit 3f9b489

Browse files
authored
feat: add solutions to lc problem: No.3031 (#2317)
No.3031.Minimum Time to Revert Word to Initial State II
1 parent 7276c22 commit 3f9b489

File tree

6 files changed

+387
-9
lines changed

6 files changed

+387
-9
lines changed

solution/3000-3099/3031.Minimum Time to Revert Word to Initial State II/README.md

+135-5
Original file line numberDiff line numberDiff line change
@@ -65,24 +65,154 @@
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+
因此,我们可以枚举操作次数,利用字符串哈希来判断两个字符串是否相等。
75+
76+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为 `word` 的长度。
6977

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

7280
```python
73-
81+
class Hashing:
82+
__slots__ = ["mod", "h", "p"]
83+
84+
def __init__(self, s: str, base: int, mod: int):
85+
self.mod = mod
86+
self.h = [0] * (len(s) + 1)
87+
self.p = [1] * (len(s) + 1)
88+
for i in range(1, len(s) + 1):
89+
self.h[i] = (self.h[i - 1] * base + ord(s[i - 1])) % mod
90+
self.p[i] = (self.p[i - 1] * base) % mod
91+
92+
def query(self, l: int, r: int) -> int:
93+
return (self.h[r] - self.h[l - 1] * self.p[r - l + 1]) % self.mod
94+
95+
96+
class Solution:
97+
def minimumTimeToInitialState(self, word: str, k: int) -> int:
98+
hashing = Hashing(word, 13331, 998244353)
99+
n = len(word)
100+
for i in range(k, n, k):
101+
if hashing.query(1, n - i) == hashing.query(i + 1, n):
102+
return i // k
103+
return (n + k - 1) // k
74104
```
75105

76106
```java
77-
107+
class Hashing {
108+
private final long[] p;
109+
private final long[] h;
110+
private final long mod;
111+
112+
public Hashing(String word, long base, int mod) {
113+
int n = word.length();
114+
p = new long[n + 1];
115+
h = new long[n + 1];
116+
p[0] = 1;
117+
this.mod = mod;
118+
for (int i = 1; i <= n; i++) {
119+
p[i] = p[i - 1] * base % mod;
120+
h[i] = (h[i - 1] * base + word.charAt(i - 1) - 'a') % mod;
121+
}
122+
}
123+
124+
public long query(int l, int r) {
125+
return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
126+
}
127+
}
128+
129+
class Solution {
130+
public int minimumTimeToInitialState(String word, int k) {
131+
Hashing hashing = new Hashing(word, 13331, 998244353);
132+
int n = word.length();
133+
for (int i = k; i < n; i += k) {
134+
if (hashing.query(1, n - i) == hashing.query(i + 1, n)) {
135+
return i / k;
136+
}
137+
}
138+
return (n + k - 1) / k;
139+
}
140+
}
78141
```
79142

80143
```cpp
81-
144+
class Hashing {
145+
private:
146+
vector<long long> p;
147+
vector<long long> h;
148+
long long mod;
149+
150+
public:
151+
Hashing(string word, long long base, int mod) {
152+
int n = word.size();
153+
p.resize(n + 1);
154+
h.resize(n + 1);
155+
p[0] = 1;
156+
this->mod = mod;
157+
for (int i = 1; i <= n; i++) {
158+
p[i] = (p[i - 1] * base) % mod;
159+
h[i] = (h[i - 1] * base + word[i - 1] - 'a') % mod;
160+
}
161+
}
162+
163+
long long query(int l, int r) {
164+
return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
165+
}
166+
};
167+
168+
class Solution {
169+
public:
170+
int minimumTimeToInitialState(string word, int k) {
171+
Hashing hashing(word, 13331, 998244353);
172+
int n = word.size();
173+
for (int i = k; i < n; i += k) {
174+
if (hashing.query(1, n - i) == hashing.query(i + 1, n)) {
175+
return i / k;
176+
}
177+
}
178+
return (n + k - 1) / k;
179+
}
180+
};
82181
```
83182
84183
```go
85-
184+
type Hashing struct {
185+
p []int64
186+
h []int64
187+
mod int64
188+
}
189+
190+
func NewHashing(word string, base int64, mod int64) *Hashing {
191+
n := len(word)
192+
p := make([]int64, n+1)
193+
h := make([]int64, n+1)
194+
p[0] = 1
195+
for i := 1; i <= n; i++ {
196+
p[i] = (p[i-1] * base) % mod
197+
h[i] = (h[i-1]*base + int64(word[i-1]-'a')) % mod
198+
}
199+
return &Hashing{p, h, mod}
200+
}
201+
202+
func (hashing *Hashing) Query(l, r int) int64 {
203+
return (hashing.h[r] - hashing.h[l-1]*hashing.p[r-l+1]%hashing.mod + hashing.mod) % hashing.mod
204+
}
205+
206+
func minimumTimeToInitialState(word string, k int) int {
207+
hashing := NewHashing(word, 13331, 998244353)
208+
n := len(word)
209+
for i := k; i < n; i += k {
210+
if hashing.Query(1, n-i) == hashing.Query(i+1, n) {
211+
return i / k
212+
}
213+
}
214+
return (n + k - 1) / k
215+
}
86216
```
87217

88218
<!-- tabs:end -->

solution/3000-3099/3031.Minimum Time to Revert Word to Initial State II/README_EN.md

+126-4
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,141 @@ It can be shown that 4 seconds is the minimum time greater than zero required fo
6363
<!-- tabs:start -->
6464

6565
```python
66-
66+
class Hashing:
67+
__slots__ = ["mod", "h", "p"]
68+
69+
def __init__(self, s: str, base: int, mod: int):
70+
self.mod = mod
71+
self.h = [0] * (len(s) + 1)
72+
self.p = [1] * (len(s) + 1)
73+
for i in range(1, len(s) + 1):
74+
self.h[i] = (self.h[i - 1] * base + ord(s[i - 1])) % mod
75+
self.p[i] = (self.p[i - 1] * base) % mod
76+
77+
def query(self, l: int, r: int) -> int:
78+
return (self.h[r] - self.h[l - 1] * self.p[r - l + 1]) % self.mod
79+
80+
81+
class Solution:
82+
def minimumTimeToInitialState(self, word: str, k: int) -> int:
83+
hashing = Hashing(word, 13331, 998244353)
84+
n = len(word)
85+
for i in range(k, n, k):
86+
if hashing.query(1, n - i) == hashing.query(i + 1, n):
87+
return i // k
88+
return (n + k - 1) // k
6789
```
6890

6991
```java
70-
92+
class Hashing {
93+
private final long[] p;
94+
private final long[] h;
95+
private final long mod;
96+
97+
public Hashing(String word, long base, int mod) {
98+
int n = word.length();
99+
p = new long[n + 1];
100+
h = new long[n + 1];
101+
p[0] = 1;
102+
this.mod = mod;
103+
for (int i = 1; i <= n; i++) {
104+
p[i] = p[i - 1] * base % mod;
105+
h[i] = (h[i - 1] * base + word.charAt(i - 1) - 'a') % mod;
106+
}
107+
}
108+
109+
public long query(int l, int r) {
110+
return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
111+
}
112+
}
113+
114+
class Solution {
115+
public int minimumTimeToInitialState(String word, int k) {
116+
Hashing hashing = new Hashing(word, 13331, 998244353);
117+
int n = word.length();
118+
for (int i = k; i < n; i += k) {
119+
if (hashing.query(1, n - i) == hashing.query(i + 1, n)) {
120+
return i / k;
121+
}
122+
}
123+
return (n + k - 1) / k;
124+
}
125+
}
71126
```
72127

73128
```cpp
74-
129+
class Hashing {
130+
private:
131+
vector<long long> p;
132+
vector<long long> h;
133+
long long mod;
134+
135+
public:
136+
Hashing(string word, long long base, int mod) {
137+
int n = word.size();
138+
p.resize(n + 1);
139+
h.resize(n + 1);
140+
p[0] = 1;
141+
this->mod = mod;
142+
for (int i = 1; i <= n; i++) {
143+
p[i] = (p[i - 1] * base) % mod;
144+
h[i] = (h[i - 1] * base + word[i - 1] - 'a') % mod;
145+
}
146+
}
147+
148+
long long query(int l, int r) {
149+
return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
150+
}
151+
};
152+
153+
class Solution {
154+
public:
155+
int minimumTimeToInitialState(string word, int k) {
156+
Hashing hashing(word, 13331, 998244353);
157+
int n = word.size();
158+
for (int i = k; i < n; i += k) {
159+
if (hashing.query(1, n - i) == hashing.query(i + 1, n)) {
160+
return i / k;
161+
}
162+
}
163+
return (n + k - 1) / k;
164+
}
165+
};
75166
```
76167
77168
```go
78-
169+
type Hashing struct {
170+
p []int64
171+
h []int64
172+
mod int64
173+
}
174+
175+
func NewHashing(word string, base int64, mod int64) *Hashing {
176+
n := len(word)
177+
p := make([]int64, n+1)
178+
h := make([]int64, n+1)
179+
p[0] = 1
180+
for i := 1; i <= n; i++ {
181+
p[i] = (p[i-1] * base) % mod
182+
h[i] = (h[i-1]*base + int64(word[i-1]-'a')) % mod
183+
}
184+
return &Hashing{p, h, mod}
185+
}
186+
187+
func (hashing *Hashing) Query(l, r int) int64 {
188+
return (hashing.h[r] - hashing.h[l-1]*hashing.p[r-l+1]%hashing.mod + hashing.mod) % hashing.mod
189+
}
190+
191+
func minimumTimeToInitialState(word string, k int) int {
192+
hashing := NewHashing(word, 13331, 998244353)
193+
n := len(word)
194+
for i := k; i < n; i += k {
195+
if hashing.Query(1, n-i) == hashing.Query(i+1, n) {
196+
return i / k
197+
}
198+
}
199+
return (n + k - 1) / k
200+
}
79201
```
80202

81203
<!-- tabs:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
class Hashing {
2+
private:
3+
vector<long long> p;
4+
vector<long long> h;
5+
long long mod;
6+
7+
public:
8+
Hashing(string word, long long base, int mod) {
9+
int n = word.size();
10+
p.resize(n + 1);
11+
h.resize(n + 1);
12+
p[0] = 1;
13+
this->mod = mod;
14+
for (int i = 1; i <= n; i++) {
15+
p[i] = (p[i - 1] * base) % mod;
16+
h[i] = (h[i - 1] * base + word[i - 1] - 'a') % mod;
17+
}
18+
}
19+
20+
long long query(int l, int r) {
21+
return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
22+
}
23+
};
24+
25+
class Solution {
26+
public:
27+
int minimumTimeToInitialState(string word, int k) {
28+
Hashing hashing(word, 13331, 998244353);
29+
int n = word.size();
30+
for (int i = k; i < n; i += k) {
31+
if (hashing.query(1, n - i) == hashing.query(i + 1, n)) {
32+
return i / k;
33+
}
34+
}
35+
return (n + k - 1) / k;
36+
}
37+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
type Hashing struct {
2+
p []int64
3+
h []int64
4+
mod int64
5+
}
6+
7+
func NewHashing(word string, base int64, mod int64) *Hashing {
8+
n := len(word)
9+
p := make([]int64, n+1)
10+
h := make([]int64, n+1)
11+
p[0] = 1
12+
for i := 1; i <= n; i++ {
13+
p[i] = (p[i-1] * base) % mod
14+
h[i] = (h[i-1]*base + int64(word[i-1]-'a')) % mod
15+
}
16+
return &Hashing{p, h, mod}
17+
}
18+
19+
func (hashing *Hashing) Query(l, r int) int64 {
20+
return (hashing.h[r] - hashing.h[l-1]*hashing.p[r-l+1]%hashing.mod + hashing.mod) % hashing.mod
21+
}
22+
23+
func minimumTimeToInitialState(word string, k int) int {
24+
hashing := NewHashing(word, 13331, 998244353)
25+
n := len(word)
26+
for i := k; i < n; i += k {
27+
if hashing.Query(1, n-i) == hashing.Query(i+1, n) {
28+
return i / k
29+
}
30+
}
31+
return (n + k - 1) / k
32+
}

0 commit comments

Comments
 (0)