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 551577c

Browse files
feat: add solutions to lc problems: No.2156,3109 (doocs#2568)
* No.2156.Find Substring With Given Hash Value * No.3109.Find the Index of Permutation
1 parent 50c804c commit 551577c

File tree

22 files changed

+1246
-79
lines changed

22 files changed

+1246
-79
lines changed

‎solution/0400-0499/0438.Find All Anagrams in a String/README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@ function findAnagrams(s: string, p: string): number[] {
364364
if (m < n) {
365365
return ans;
366366
}
367-
const cnt1: number[] = newArray(26).fill(0);
368-
const cnt2: number[] = newArray(26).fill(0);
367+
const cnt1: number[] = Array(26).fill(0);
368+
const cnt2: number[] = Array(26).fill(0);
369369
const idx = (c: string) => c.charCodeAt(0) - 'a'.charCodeAt(0);
370370
for (const c of p) {
371371
++cnt1[idx(c)];

‎solution/0400-0499/0438.Find All Anagrams in a String/README_EN.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,8 @@ function findAnagrams(s: string, p: string): number[] {
348348
if (m < n) {
349349
return ans;
350350
}
351-
const cnt1: number[] = newArray(26).fill(0);
352-
const cnt2: number[] = newArray(26).fill(0);
351+
const cnt1: number[] = Array(26).fill(0);
352+
const cnt2: number[] = Array(26).fill(0);
353353
const idx = (c: string) => c.charCodeAt(0) - 'a'.charCodeAt(0);
354354
for (const c of p) {
355355
++cnt1[idx(c)];

‎solution/0400-0499/0438.Find All Anagrams in a String/Solution2.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ function findAnagrams(s: string, p: string): number[] {
55
if (m < n) {
66
return ans;
77
}
8-
const cnt1: number[] = newArray(26).fill(0);
9-
const cnt2: number[] = newArray(26).fill(0);
8+
const cnt1: number[] = Array(26).fill(0);
9+
const cnt2: number[] = Array(26).fill(0);
1010
const idx = (c: string) => c.charCodeAt(0) - 'a'.charCodeAt(0);
1111
for (const c of p) {
1212
++cnt1[idx(c)];

‎solution/1700-1799/1766.Tree of Coprimes/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565

6666
接下来我们可以使用回溯的方法,从根节点开始遍历整棵树,对于每个节点 $i,ドル我们可以通过 $f$ 数组得到 $nums[i]$ 的所有互质数。然后我们枚举 $nums[i]$ 的所有互质数,找到已经出现过的且深度最大的祖先节点 $t,ドル即为 $i$ 的最近的互质祖先节点。这里我们可以用一个长度为 51ドル$ 的栈数组 $stks$ 来获取每个出现过的值 $v$ 的节点以及其深度。每个栈 $stks[v]$ 的栈顶元素就是最近的深度最大的祖先节点。
6767

68-
时间复杂度 $O(n),ドル空间复杂度 $O(n)$。其中 $n$ 为节点个数。
68+
时间复杂度 $O(n \times M),ドル空间复杂度 $O(M^2 + n)$。其中 $n$ 为节点个数,而 $M$ 为 $nums[i]$ 的最大值,本题中 $M = 50$
6969

7070
<!-- tabs:start -->
7171

‎solution/1700-1799/1766.Tree of Coprimes/README_EN.md‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,13 @@
5757

5858
## Solutions
5959

60-
### Solution 1
60+
### Solution 1: Preprocessing + Enumeration + Stack + Backtracking
61+
62+
Since the range of $nums[i]$ in the problem is $[1, 50],ドル we can preprocess all the coprime numbers for each number and record them in the array $f,ドル where $f[i]$ represents all the coprime numbers of $i$.
63+
64+
Next, we can use a backtracking method to traverse the entire tree from the root node. For each node $i,ドル we can get all the coprime numbers of $nums[i]$ through the array $f$. Then we enumerate all the coprime numbers of $nums[i],ドル find the ancestor node $t$ that has appeared and has the maximum depth, which is the nearest coprime ancestor node of $i$. Here we can use a stack array $stks$ of length 51ドル$ to get each appeared value $v$ and its depth. The top element of each stack $stks[v]$ is the nearest ancestor node with the maximum depth.
65+
66+
The time complexity is $O(n \times M),ドル and the space complexity is $O(M^2 + n)$. Where $n$ is the number of nodes, and $M$ is the maximum value of $nums[i],ドル in this problem $M = 50$.
6167

6268
<!-- tabs:start -->
6369

‎solution/2100-2199/2156.Find Substring With Given Hash Value/README.md‎

Lines changed: 157 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,149 @@
5656

5757
## 解法
5858

59-
### 方法一
59+
### 方法一:滑动窗口 + 倒序遍历
60+
61+
我们可以维护一个长度为 $k$ 的滑动窗口,用来计算子串的哈希值。考虑到如果正序遍历字符串,在哈希值的计算中,涉及到除法取模的操作,处理起来比较麻烦。因此我们可以倒序遍历字符串,这样在计算哈希值的时候,只需要乘法和取模操作。
62+
63+
我们首先计算字符串末尾的 $k$ 个字符的哈希值,然后从字符串末尾开始倒序遍历,每次计算当前窗口的哈希值,如果等于给定的哈希值,我们就找到了一个满足条件的子串,更新答案字符串的起始位置。
64+
65+
最后返回答案字符串即可。
66+
67+
时间复杂度 $O(n),ドル其中 $n$ 是字符串的长度。空间复杂度 $O(1)$。
6068

6169
<!-- tabs:start -->
6270

71+
```python
72+
class Solution:
73+
def subStrHash(
74+
self, s: str, power: int, modulo: int, k: int, hashValue: int
75+
) -> str:
76+
h, n = 0, len(s)
77+
p = 1
78+
for i in range(n - 1, n - 1 - k, -1):
79+
val = ord(s[i]) - ord("a") + 1
80+
h = ((h * power) + val) % modulo
81+
if i != n - k:
82+
p = p * power % modulo
83+
j = n - k
84+
for i in range(n - 1 - k, -1, -1):
85+
pre = ord(s[i + k]) - ord("a") + 1
86+
cur = ord(s[i]) - ord("a") + 1
87+
h = ((h - pre * p) * power + cur) % modulo
88+
if h == hashValue:
89+
j = i
90+
return s[j : j + k]
91+
```
92+
93+
```java
94+
class Solution {
95+
public String subStrHash(String s, int power, int modulo, int k, int hashValue) {
96+
long h = 0, p = 1;
97+
int n = s.length();
98+
for (int i = n - 1; i >= n - k; --i) {
99+
int val = s.charAt(i) - 'a' + 1;
100+
h = ((h * power % modulo) + val) % modulo;
101+
if (i != n - k) {
102+
p = p * power % modulo;
103+
}
104+
}
105+
int j = n - k;
106+
for (int i = n - k - 1; i >= 0; --i) {
107+
int pre = s.charAt(i + k) - 'a' + 1;
108+
int cur = s.charAt(i) - 'a' + 1;
109+
h = ((h - pre * p % modulo + modulo) * power % modulo + cur) % modulo;
110+
if (h == hashValue) {
111+
j = i;
112+
}
113+
}
114+
return s.substring(j, j + k);
115+
}
116+
}
117+
```
118+
119+
```cpp
120+
class Solution {
121+
public:
122+
string subStrHash(string s, int power, int modulo, int k, int hashValue) {
123+
long long h = 0, p = 1;
124+
int n = s.size();
125+
for (int i = n - 1; i >= n - k; --i) {
126+
int val = s[i] - 'a' + 1;
127+
h = ((h * power % modulo) + val) % modulo;
128+
if (i != n - k) {
129+
p = p * power % modulo;
130+
}
131+
}
132+
int j = n - k;
133+
for (int i = n - k - 1; i >= 0; --i) {
134+
int pre = s[i + k] - 'a' + 1;
135+
int cur = s[i] - 'a' + 1;
136+
h = ((h - pre * p % modulo + modulo) * power % modulo + cur) % modulo;
137+
if (h == hashValue) {
138+
j = i;
139+
}
140+
}
141+
return s.substr(j, k);
142+
}
143+
};
144+
```
145+
146+
```go
147+
func subStrHash(s string, power int, modulo int, k int, hashValue int) string {
148+
h, p := 0, 1
149+
n := len(s)
150+
for i := n - 1; i >= n-k; i-- {
151+
val := int(s[i] - 'a' + 1)
152+
h = (h*power%modulo + val) % modulo
153+
if i != n-k {
154+
p = p * power % modulo
155+
}
156+
}
157+
j := n - k
158+
for i := n - k - 1; i >= 0; i-- {
159+
pre := int(s[i+k] - 'a' + 1)
160+
cur := int(s[i] - 'a' + 1)
161+
h = ((h-pre*p%modulo+modulo)*power%modulo + cur) % modulo
162+
if h == hashValue {
163+
j = i
164+
}
165+
}
166+
return s[j : j+k]
167+
}
168+
```
169+
170+
```ts
171+
function subStrHash(
172+
s: string,
173+
power: number,
174+
modulo: number,
175+
k: number,
176+
hashValue: number,
177+
): string {
178+
let h: bigint = BigInt(0),
179+
p: bigint = BigInt(1);
180+
const n: number = s.length;
181+
const mod = BigInt(modulo);
182+
for (let i: number = n - 1; i >= n - k; --i) {
183+
const val: bigint = BigInt(s.charCodeAt(i) - 'a'.charCodeAt(0) + 1);
184+
h = (((h * BigInt(power)) % mod) + val) % mod;
185+
if (i !== n - k) {
186+
p = (p * BigInt(power)) % mod;
187+
}
188+
}
189+
let j: number = n - k;
190+
for (let i: number = n - k - 1; i >= 0; --i) {
191+
const pre: bigint = BigInt(s.charCodeAt(i + k) - 'a'.charCodeAt(0) + 1);
192+
const cur: bigint = BigInt(s.charCodeAt(i) - 'a'.charCodeAt(0) + 1);
193+
h = ((((h - ((pre * p) % mod) + mod) * BigInt(power)) % mod) + cur) % mod;
194+
if (Number(h) === hashValue) {
195+
j = i;
196+
}
197+
}
198+
return s.substring(j, j + k);
199+
}
200+
```
201+
63202
```js
64203
/**
65204
* @param {string} s
@@ -70,34 +209,28 @@
70209
* @return {string}
71210
*/
72211
var subStrHash = function (s, power, modulo, k, hashValue) {
73-
power = BigInt(power);
74-
modulo = BigInt(modulo);
75-
hashValue = BigInt(hashValue);
212+
let h = BigInt(0),
213+
p = BigInt(1);
76214
const n = s.length;
77-
let pk = 1n;
78-
let ac = 0n;
79-
// 倒序滑动窗口
80-
for (let i = n - 1; i > n - 1 - k; i--) {
81-
ac = (ac * power + getCode(s, i)) % modulo;
82-
pk = (pk * power) % modulo;
83-
}
84-
let ans = -1;
85-
if (ac == hashValue) {
86-
ans = n - k;
215+
const mod = BigInt(modulo);
216+
for (let i = n - 1; i >= n - k; --i) {
217+
const val = BigInt(s.charCodeAt(i) - 'a'.charCodeAt(0) + 1);
218+
h = (((h * BigInt(power)) % mod) + val) % mod;
219+
if (i !== n - k) {
220+
p = (p * BigInt(power)) % mod;
221+
}
87222
}
88-
for (let i = n - 1 - k; i >= 0; i--) {
89-
let pre = (getCode(s, i + k) * pk) % modulo;
90-
ac = (ac * power + getCode(s, i) - pre + modulo) % modulo;
91-
if (ac == hashValue) {
92-
ans = i;
223+
let j = n - k;
224+
for (let i = n - k - 1; i >= 0; --i) {
225+
const pre = BigInt(s.charCodeAt(i + k) - 'a'.charCodeAt(0) + 1);
226+
const cur = BigInt(s.charCodeAt(i) - 'a'.charCodeAt(0) + 1);
227+
h = ((((h - ((pre * p) % mod) + mod) * BigInt(power)) % mod) + cur) % mod;
228+
if (Number(h) === hashValue) {
229+
j = i;
93230
}
94231
}
95-
return ans ==-1?'':s.substring(ans, ans + k);
232+
return s.substring(j, j + k);
96233
};
97-
98-
function getCode(str, index) {
99-
return BigInt(str.charCodeAt(index) - 'a'.charCodeAt(0) + 1);
100-
}
101234
```
102235

103236
<!-- tabs:end -->

0 commit comments

Comments
(0)

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