graph
dfs
sliding window
union find
greater to smaller
]
BinarySearch 0507 Special Nodes
Problem statement
https://binarysearch.com/problems/Special-Nodes/
Solution 1
First solution is to notice that if we keep sets for unique colors for each node and when we merget two children and follow the strategy: merge smaller to bigger, than we will have good complexity: I think it can be proved that it is O(n log n)
. In python when we traverse tree with dfs, what is returned is pointer to array, not the copy, that is why it works.
Complexity
It is O(n log n)
for time and O(n)
for space.
Code
class Solution:
def solve(self, tree, color):
self.ans = 0
def dfs(par, node):
ans, cnt = set([color[node]]), 1
for child in tree[node]:
if child == par: continue
x, cnt_x = dfs(node, child)
if len(x) > len(ans):
x |= ans
ans = x
else:
ans |= x
cnt += cnt_x
self.ans += (len(ans) == cnt)
return ans, cnt
dfs(-1, 0)
return self.ans
Solution 2
There is another solution using euler traversal of graph, or pre-order traversal.
col
is colors of nodes in our traversal.beg
is first encounter of nodei
.end
is the last encounter of nodei
. Now subtree is kept in[beg, end]
.
Now, we have two main steps:
- Traverse tree to get
col, beg, end
. -
Use sliding window (two pointers approach) to answer for each start what is the rightest point we can reach such that all colors are different.
f
is color counterd
is the look back index ranging to where the colors are uniquej
is the front pointer for the two pointers way of iterating the unique-color-ranges
Complexity
It is O(n)
for time and space.
Code
class Solution:
def solve(self, tree, color):
n = len(color)
beg, end, col, d = [0]*n, [0]*n ,[0]*n, [0]*n
self.idx = 0
def dfs(par, node):
col[self.idx] = color[node]
beg[node]= self.idx
self.idx += 1
for child in tree[node]:
if child != par: dfs(node, child)
end[node] = self.idx
dfs(-1, 0)
f = Counter()
j = -1
for i in range(n):
while f[col[i]]:
j += 1
f[col[j]] -= 1
f[col[i]] += 1
d[i] = j
return sum(d[end[x] - 1] < beg[x] for x in range(n))
Remark
There is also solution using union find.