Skip to content

Commit

Permalink
feat: add solutions to lc problem: No.3031 (#2317)
Browse files Browse the repository at this point in the history
No.3031.Minimum Time to Revert Word to Initial State II
  • Loading branch information
yanglbme authored Feb 4, 2024
1 parent 7276c22 commit 3f9b489
Show file tree
Hide file tree
Showing 6 changed files with 387 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,24 +65,154 @@

## 解法

### 方法一
### 方法一:枚举 + 字符串哈希

我们不妨假设,如果只操作一次,就能使得 `word` 恢复到初始状态,那么意味着 `word[k:]``word` 的前缀,即 `word[k:] == word[:n-k]`

如果有多次操作,不妨设 $i$ 为操作次数,那么意味着 `word[k*i:]``word` 的前缀,即 `word[k*i:] == word[:n-k*i]`

因此,我们可以枚举操作次数,利用字符串哈希来判断两个字符串是否相等。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为 `word` 的长度。

<!-- tabs:start -->

```python

class Hashing:
__slots__ = ["mod", "h", "p"]

def __init__(self, s: str, base: int, mod: int):
self.mod = mod
self.h = [0] * (len(s) + 1)
self.p = [1] * (len(s) + 1)
for i in range(1, len(s) + 1):
self.h[i] = (self.h[i - 1] * base + ord(s[i - 1])) % mod
self.p[i] = (self.p[i - 1] * base) % mod

def query(self, l: int, r: int) -> int:
return (self.h[r] - self.h[l - 1] * self.p[r - l + 1]) % self.mod


class Solution:
def minimumTimeToInitialState(self, word: str, k: int) -> int:
hashing = Hashing(word, 13331, 998244353)
n = len(word)
for i in range(k, n, k):
if hashing.query(1, n - i) == hashing.query(i + 1, n):
return i // k
return (n + k - 1) // k
```

```java

class Hashing {
private final long[] p;
private final long[] h;
private final long mod;

public Hashing(String word, long base, int mod) {
int n = word.length();
p = new long[n + 1];
h = new long[n + 1];
p[0] = 1;
this.mod = mod;
for (int i = 1; i <= n; i++) {
p[i] = p[i - 1] * base % mod;
h[i] = (h[i - 1] * base + word.charAt(i - 1) - 'a') % mod;
}
}

public long query(int l, int r) {
return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
}
}

class Solution {
public int minimumTimeToInitialState(String word, int k) {
Hashing hashing = new Hashing(word, 13331, 998244353);
int n = word.length();
for (int i = k; i < n; i += k) {
if (hashing.query(1, n - i) == hashing.query(i + 1, n)) {
return i / k;
}
}
return (n + k - 1) / k;
}
}
```

```cpp

class Hashing {
private:
vector<long long> p;
vector<long long> h;
long long mod;

public:
Hashing(string word, long long base, int mod) {
int n = word.size();
p.resize(n + 1);
h.resize(n + 1);
p[0] = 1;
this->mod = mod;
for (int i = 1; i <= n; i++) {
p[i] = (p[i - 1] * base) % mod;
h[i] = (h[i - 1] * base + word[i - 1] - 'a') % mod;
}
}

long long query(int l, int r) {
return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
}
};

class Solution {
public:
int minimumTimeToInitialState(string word, int k) {
Hashing hashing(word, 13331, 998244353);
int n = word.size();
for (int i = k; i < n; i += k) {
if (hashing.query(1, n - i) == hashing.query(i + 1, n)) {
return i / k;
}
}
return (n + k - 1) / k;
}
};
```
```go

type Hashing struct {
p []int64
h []int64
mod int64
}
func NewHashing(word string, base int64, mod int64) *Hashing {
n := len(word)
p := make([]int64, n+1)
h := make([]int64, n+1)
p[0] = 1
for i := 1; i <= n; i++ {
p[i] = (p[i-1] * base) % mod
h[i] = (h[i-1]*base + int64(word[i-1]-'a')) % mod
}
return &Hashing{p, h, mod}
}
func (hashing *Hashing) Query(l, r int) int64 {
return (hashing.h[r] - hashing.h[l-1]*hashing.p[r-l+1]%hashing.mod + hashing.mod) % hashing.mod
}
func minimumTimeToInitialState(word string, k int) int {
hashing := NewHashing(word, 13331, 998244353)
n := len(word)
for i := k; i < n; i += k {
if hashing.Query(1, n-i) == hashing.Query(i+1, n) {
return i / k
}
}
return (n + k - 1) / k
}
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,141 @@ It can be shown that 4 seconds is the minimum time greater than zero required fo
<!-- tabs:start -->

```python

class Hashing:
__slots__ = ["mod", "h", "p"]

def __init__(self, s: str, base: int, mod: int):
self.mod = mod
self.h = [0] * (len(s) + 1)
self.p = [1] * (len(s) + 1)
for i in range(1, len(s) + 1):
self.h[i] = (self.h[i - 1] * base + ord(s[i - 1])) % mod
self.p[i] = (self.p[i - 1] * base) % mod

def query(self, l: int, r: int) -> int:
return (self.h[r] - self.h[l - 1] * self.p[r - l + 1]) % self.mod


class Solution:
def minimumTimeToInitialState(self, word: str, k: int) -> int:
hashing = Hashing(word, 13331, 998244353)
n = len(word)
for i in range(k, n, k):
if hashing.query(1, n - i) == hashing.query(i + 1, n):
return i // k
return (n + k - 1) // k
```

```java

class Hashing {
private final long[] p;
private final long[] h;
private final long mod;

public Hashing(String word, long base, int mod) {
int n = word.length();
p = new long[n + 1];
h = new long[n + 1];
p[0] = 1;
this.mod = mod;
for (int i = 1; i <= n; i++) {
p[i] = p[i - 1] * base % mod;
h[i] = (h[i - 1] * base + word.charAt(i - 1) - 'a') % mod;
}
}

public long query(int l, int r) {
return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
}
}

class Solution {
public int minimumTimeToInitialState(String word, int k) {
Hashing hashing = new Hashing(word, 13331, 998244353);
int n = word.length();
for (int i = k; i < n; i += k) {
if (hashing.query(1, n - i) == hashing.query(i + 1, n)) {
return i / k;
}
}
return (n + k - 1) / k;
}
}
```

```cpp

class Hashing {
private:
vector<long long> p;
vector<long long> h;
long long mod;

public:
Hashing(string word, long long base, int mod) {
int n = word.size();
p.resize(n + 1);
h.resize(n + 1);
p[0] = 1;
this->mod = mod;
for (int i = 1; i <= n; i++) {
p[i] = (p[i - 1] * base) % mod;
h[i] = (h[i - 1] * base + word[i - 1] - 'a') % mod;
}
}

long long query(int l, int r) {
return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
}
};

class Solution {
public:
int minimumTimeToInitialState(string word, int k) {
Hashing hashing(word, 13331, 998244353);
int n = word.size();
for (int i = k; i < n; i += k) {
if (hashing.query(1, n - i) == hashing.query(i + 1, n)) {
return i / k;
}
}
return (n + k - 1) / k;
}
};
```
```go

type Hashing struct {
p []int64
h []int64
mod int64
}
func NewHashing(word string, base int64, mod int64) *Hashing {
n := len(word)
p := make([]int64, n+1)
h := make([]int64, n+1)
p[0] = 1
for i := 1; i <= n; i++ {
p[i] = (p[i-1] * base) % mod
h[i] = (h[i-1]*base + int64(word[i-1]-'a')) % mod
}
return &Hashing{p, h, mod}
}
func (hashing *Hashing) Query(l, r int) int64 {
return (hashing.h[r] - hashing.h[l-1]*hashing.p[r-l+1]%hashing.mod + hashing.mod) % hashing.mod
}
func minimumTimeToInitialState(word string, k int) int {
hashing := NewHashing(word, 13331, 998244353)
n := len(word)
for i := k; i < n; i += k {
if hashing.Query(1, n-i) == hashing.Query(i+1, n) {
return i / k
}
}
return (n + k - 1) / k
}
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class Hashing {
private:
vector<long long> p;
vector<long long> h;
long long mod;

public:
Hashing(string word, long long base, int mod) {
int n = word.size();
p.resize(n + 1);
h.resize(n + 1);
p[0] = 1;
this->mod = mod;
for (int i = 1; i <= n; i++) {
p[i] = (p[i - 1] * base) % mod;
h[i] = (h[i - 1] * base + word[i - 1] - 'a') % mod;
}
}

long long query(int l, int r) {
return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
}
};

class Solution {
public:
int minimumTimeToInitialState(string word, int k) {
Hashing hashing(word, 13331, 998244353);
int n = word.size();
for (int i = k; i < n; i += k) {
if (hashing.query(1, n - i) == hashing.query(i + 1, n)) {
return i / k;
}
}
return (n + k - 1) / k;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
type Hashing struct {
p []int64
h []int64
mod int64
}

func NewHashing(word string, base int64, mod int64) *Hashing {
n := len(word)
p := make([]int64, n+1)
h := make([]int64, n+1)
p[0] = 1
for i := 1; i <= n; i++ {
p[i] = (p[i-1] * base) % mod
h[i] = (h[i-1]*base + int64(word[i-1]-'a')) % mod
}
return &Hashing{p, h, mod}
}

func (hashing *Hashing) Query(l, r int) int64 {
return (hashing.h[r] - hashing.h[l-1]*hashing.p[r-l+1]%hashing.mod + hashing.mod) % hashing.mod
}

func minimumTimeToInitialState(word string, k int) int {
hashing := NewHashing(word, 13331, 998244353)
n := len(word)
for i := k; i < n; i += k {
if hashing.Query(1, n-i) == hashing.Query(i+1, n) {
return i / k
}
}
return (n + k - 1) / k
}
Loading

0 comments on commit 3f9b489

Please sign in to comment.