Skip to content

Commit 64c12b1

Browse files
authored
feat: update solutions to lc problem: No.3327 (#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

+233-5
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)