@@ -95,32 +95,260 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3327.Ch
95
95
96
96
<!-- solution:start -->
97
97
98
- ### 方法一
98
+ ### 方法一:DFS + 字符串哈希
99
+
100
+ 我们可以使用深度优先搜索(DFS)来遍历树,将整棵树的 $\textit{dfsStr}$ 求出来,顺便求出每个节点的区间 $[ l, r] $。
101
+
102
+ 然后我们使用字符串哈希的方法,分别求出 $\textit{dfsStr}$ 和 $\textit{dfsStr}$ 的逆序串的哈希值,判断是否是回文串。
103
+
104
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $s$ 的长度。
99
105
100
106
<!-- tabs:start -->
101
107
102
108
#### Python3
103
109
104
110
``` 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
106
155
```
107
156
108
157
#### Java
109
158
110
159
``` 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
+ }
112
223
```
113
224
114
225
#### C++
115
226
116
227
``` 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
+ };
118
289
```
119
290
120
291
#### Go
121
292
122
293
``` 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
+ }
124
352
```
125
353
126
354
<!-- tabs:end -->
0 commit comments