Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 1d97527

Browse files
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‎

Lines changed: 175 additions & 71 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /