@@ -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