-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathcheck-if-dfs-strings-are-palindromes.py
93 lines (86 loc) · 2.68 KB
/
check-if-dfs-strings-are-palindromes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# Time: O(n)
# Space: O(n)
# iterative dfs, manacher's algorithm
class Solution(object):
def findAnswer(self, parent, s):
"""
:type parent: List[int]
:type s: str
:rtype: List[bool]
"""
def manacher(s):
s = '^#' + '#'.join(s) + '#$'
P = [0]*len(s)
C, R = 0, 0
for i in xrange(1, len(s)-1):
i_mirror = 2*C-i
if R > i:
P[i] = min(R-i, P[i_mirror])
while s[i+1+P[i]] == s[i-1-P[i]]:
P[i] += 1
if i+P[i] > R:
C, R = i, i+P[i]
return P
def iter_dfs(u):
cnt = 0
curr = []
lookup = [None]*len(adj)
stk = [(1, (0,))]
while stk:
step, args = stk.pop()
if step == 1:
u = args[0]
stk.append((2, (u, cnt)))
for v in reversed(adj[u]):
stk.append((1, (v,)))
elif step == 2:
u, left = args
curr.append(s[u])
lookup[u] = (left, cnt)
cnt += 1
return curr, lookup
adj = [[] for _ in xrange(len(parent))]
for v in xrange(1, len(parent)):
adj[parent[v]].append(v)
curr, lookup = iter_dfs(0)
P = manacher(curr)
return [P[(2*(left+1)+2*(right+1))//2] >= right-left+1 for left, right in lookup]
# Time: O(n)
# Space: O(n)
# dfs, manacher's algorithm
class Solution2(object):
def findAnswer(self, parent, s):
"""
:type parent: List[int]
:type s: str
:rtype: List[bool]
"""
def manacher(s):
s = '^#' + '#'.join(s) + '#$'
P = [0]*len(s)
C, R = 0, 0
for i in xrange(1, len(s)-1):
i_mirror = 2*C-i
if R > i:
P[i] = min(R-i, P[i_mirror])
while s[i+1+P[i]] == s[i-1-P[i]]:
P[i] += 1
if i+P[i] > R:
C, R = i, i+P[i]
return P
def dfs(u):
left = cnt[0]
for v in adj[u]:
dfs(v)
curr.append(s[u])
lookup[u] = (left, cnt[0])
cnt[0] += 1
adj = [[] for _ in xrange(len(parent))]
for v in xrange(1, len(parent)):
adj[parent[v]].append(v)
cnt = [0]
curr = []
lookup = [None]*len(adj)
dfs(0)
P = manacher(curr)
return [P[(2*(left+1)+2*(right+1))//2] >= right-left+1 for left, right in lookup]