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 64c12b1

Browse files
feat: update solutions to lc problem: No.3327 (doocs#3659)
No.3327.Check if DFS Strings Are Palindromes
1 parent 36904ac commit 64c12b1

File tree

6 files changed

+692
-10
lines changed

6 files changed

+692
-10
lines changed

‎solution/3300-3399/3327.Check if DFS Strings Are Palindromes/README.md‎

Lines changed: 233 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,32 +95,260 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3327.Ch
9595

9696
<!-- solution:start -->
9797

98-
### 方法一
98+
### 方法一:DFS + 字符串哈希
99+
100+
我们可以使用深度优先搜索(DFS)来遍历树,将整棵树的 $\textit{dfsStr}$ 求出来,顺便求出每个节点的区间 $[l, r]$。
101+
102+
然后我们使用字符串哈希的方法,分别求出 $\textit{dfsStr}$ 和 $\textit{dfsStr}$ 的逆序串的哈希值,判断是否是回文串。
103+
104+
时间复杂度 $O(n),ドル空间复杂度 $O(n)$。其中 $n$ 为字符串 $s$ 的长度。
99105

100106
<!-- tabs:start -->
101107

102108
#### Python3
103109

104110
```python
105-
111+
class Hashing:
112+
__slots__ = ["mod", "h", "p"]
113+
114+
def __init__(self, s: List[str], base: int, mod: int):
115+
self.mod = mod
116+
self.h = [0] * (len(s) + 1)
117+
self.p = [1] * (len(s) + 1)
118+
for i in range(1, len(s) + 1):
119+
self.h[i] = (self.h[i - 1] * base + ord(s[i - 1])) % mod
120+
self.p[i] = (self.p[i - 1] * base) % mod
121+
122+
def query(self, l: int, r: int) -> int:
123+
return (self.h[r] - self.h[l - 1] * self.p[r - l + 1]) % self.mod
124+
125+
126+
class Solution:
127+
def findAnswer(self, parent: List[int], s: str) -> List[bool]:
128+
def dfs(i: int):
129+
l = len(dfsStr) + 1
130+
for j in g[i]:
131+
dfs(j)
132+
dfsStr.append(s[i])
133+
r = len(dfsStr)
134+
pos[i] = (l, r)
135+
136+
n = len(s)
137+
g = [[] for _ in range(n)]
138+
for i in range(1, n):
139+
g[parent[i]].append(i)
140+
dfsStr = []
141+
pos = {}
142+
dfs(0)
143+
144+
base, mod = 13331, 998244353
145+
h1 = Hashing(dfsStr, base, mod)
146+
h2 = Hashing(dfsStr[::-1], base, mod)
147+
ans = []
148+
for i in range(n):
149+
l, r = pos[i]
150+
k = r - l + 1
151+
v1 = h1.query(l, l + k // 2 - 1)
152+
v2 = h2.query(n - r + 1, n - r + 1 + k // 2 - 1)
153+
ans.append(v1 == v2)
154+
return ans
106155
```
107156

108157
#### Java
109158

110159
```java
111-
160+
class Hashing {
161+
private final long[] p;
162+
private final long[] h;
163+
private final long mod;
164+
165+
public Hashing(String word, long base, int mod) {
166+
int n = word.length();
167+
p = new long[n + 1];
168+
h = new long[n + 1];
169+
p[0] = 1;
170+
this.mod = mod;
171+
for (int i = 1; i <= n; i++) {
172+
p[i] = p[i - 1] * base % mod;
173+
h[i] = (h[i - 1] * base + word.charAt(i - 1)) % mod;
174+
}
175+
}
176+
177+
public long query(int l, int r) {
178+
return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
179+
}
180+
}
181+
182+
class Solution {
183+
private char[] s;
184+
private int[][] pos;
185+
private List<Integer>[] g;
186+
private StringBuilder dfsStr = new StringBuilder();
187+
188+
public boolean[] findAnswer(int[] parent, String s) {
189+
this.s = s.toCharArray();
190+
int n = s.length();
191+
g = new List[n];
192+
pos = new int[n][0];
193+
Arrays.setAll(g, k -> new ArrayList<>());
194+
for (int i = 1; i < n; ++i) {
195+
g[parent[i]].add(i);
196+
}
197+
dfs(0);
198+
final int base = 13331;
199+
final int mod = 998244353;
200+
Hashing h1 = new Hashing(dfsStr.toString(), base, mod);
201+
Hashing h2 = new Hashing(new StringBuilder(dfsStr).reverse().toString(), base, mod);
202+
boolean[] ans = new boolean[n];
203+
for (int i = 0; i < n; ++i) {
204+
int l = pos[i][0], r = pos[i][1];
205+
int k = r - l + 1;
206+
long v1 = h1.query(l, l + k / 2 - 1);
207+
long v2 = h2.query(n + 1 - r, n + 1 - r + k / 2 - 1);
208+
ans[i] = v1 == v2;
209+
}
210+
return ans;
211+
}
212+
213+
private void dfs(int i) {
214+
int l = dfsStr.length() + 1;
215+
for (int j : g[i]) {
216+
dfs(j);
217+
}
218+
dfsStr.append(s[i]);
219+
int r = dfsStr.length();
220+
pos[i] = new int[]{l, r};
221+
}
222+
}
112223
```
113224

114225
#### C++
115226

116227
```cpp
117-
228+
class Hashing {
229+
private:
230+
vector<long long> p;
231+
vector<long long> h;
232+
long long mod;
233+
234+
public:
235+
Hashing(string word, long long base, int mod) {
236+
int n = word.size();
237+
p.resize(n + 1);
238+
h.resize(n + 1);
239+
p[0] = 1;
240+
this->mod = mod;
241+
for (int i = 1; i <= n; i++) {
242+
p[i] = (p[i - 1] * base) % mod;
243+
h[i] = (h[i - 1] * base + word[i - 1] - 'a') % mod;
244+
}
245+
}
246+
247+
long long query(int l, int r) {
248+
return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
249+
}
250+
};
251+
252+
class Solution {
253+
public:
254+
vector<bool> findAnswer(vector<int>& parent, string s) {
255+
int n = s.size();
256+
vector<int> g[n];
257+
for (int i = 1; i < n; ++i) {
258+
g[parent[i]].push_back(i);
259+
}
260+
string dfsStr;
261+
vector<pair<int, int>> pos(n);
262+
auto dfs = [&](auto&& dfs, int i) -> void {
263+
int l = dfsStr.size() + 1;
264+
for (int j : g[i]) {
265+
dfs(dfs, j);
266+
}
267+
dfsStr.push_back(s[i]);
268+
int r = dfsStr.size();
269+
pos[i] = {l, r};
270+
};
271+
dfs(dfs, 0);
272+
273+
const int base = 13331;
274+
const int mod = 998244353;
275+
Hashing h1(dfsStr, base, mod);
276+
reverse(dfsStr.begin(), dfsStr.end());
277+
Hashing h2(dfsStr, base, mod);
278+
vector<bool> ans(n);
279+
for (int i = 0; i < n; ++i) {
280+
auto [l, r] = pos[i];
281+
int k = r - l + 1;
282+
long long v1 = h1.query(l, l + k / 2 - 1);
283+
long long v2 = h2.query(n - r + 1, n - r + 1 + k / 2 - 1);
284+
ans[i] = v1 == v2;
285+
}
286+
return ans;
287+
}
288+
};
118289
```
119290

120291
#### Go
121292

122293
```go
123-
294+
type Hashing struct {
295+
p []int64
296+
h []int64
297+
mod int64
298+
}
299+
300+
func NewHashing(word string, base, mod int64) *Hashing {
301+
n := len(word)
302+
p := make([]int64, n+1)
303+
h := make([]int64, n+1)
304+
p[0] = 1
305+
for i := 1; i <= n; i++ {
306+
p[i] = p[i-1] * base % mod
307+
h[i] = (h[i-1]*base + int64(word[i-1])) % mod
308+
}
309+
return &Hashing{p, h, mod}
310+
}
311+
312+
func (hs *Hashing) query(l, r int) int64 {
313+
return (hs.h[r] - hs.h[l-1]*hs.p[r-l+1]%hs.mod + hs.mod) % hs.mod
314+
}
315+
316+
func findAnswer(parent []int, s string) (ans []bool) {
317+
n := len(s)
318+
g := make([][]int, n)
319+
for i := 1; i < n; i++ {
320+
g[parent[i]] = append(g[parent[i]], i)
321+
}
322+
dfsStr := []byte{}
323+
pos := make([][2]int, n)
324+
var dfs func(int)
325+
dfs = func(i int) {
326+
l := len(dfsStr) + 1
327+
for _, j := range g[i] {
328+
dfs(j)
329+
}
330+
dfsStr = append(dfsStr, s[i])
331+
r := len(dfsStr)
332+
pos[i] = [2]int{l, r}
333+
}
334+
335+
const base = 13331
336+
const mod = 998244353
337+
dfs(0)
338+
h1 := NewHashing(string(dfsStr), base, mod)
339+
for i, j := 0, len(dfsStr)-1; i < j; i, j = i+1, j-1 {
340+
dfsStr[i], dfsStr[j] = dfsStr[j], dfsStr[i]
341+
}
342+
h2 := NewHashing(string(dfsStr), base, mod)
343+
for i := 0; i < n; i++ {
344+
l, r := pos[i][0], pos[i][1]
345+
k := r - l + 1
346+
v1 := h1.query(l, l+k/2-1)
347+
v2 := h2.query(n-r+1, n-r+1+k/2-1)
348+
ans = append(ans, v1 == v2)
349+
}
350+
return
351+
}
124352
```
125353

126354
<!-- tabs:end -->

0 commit comments

Comments
(0)

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