Skip to content
LC-2385 Medium LeetCode

2385. Amount of Time for Binary Tree to Be Infected

Read the full problem statement on LeetCode.
Difficulty: medium Acceptance: 63% Topics: Hash Table, Tree, Depth-First Search, Breadth-First Search, Binary Tree
View full problem on LeetCode
Reference solution (spoiler · python)
# Time:  O(n)
# Space: O(h)

# Definition for a binary tree node.
class TreeNode(object):
    def __init__(self, val=0, left=None, right=None):
        pass


# iterative dfs, tree dp
class Solution(object):
    def amountOfTime(self, root, start):
        """
        :type root: Optional[TreeNode]
        :type start: int
        :rtype: int
        """
        def iter_dfs(root, start):
            result = -1
            stk = [(1, (root, [-1]*2))]
            while stk:
                step, args = stk.pop()
                if step == 1:
                    curr, ret = args
                    if curr is None:
                        continue
                    left, right = [-1]*2, [-1]*2
                    stk.append((2, (curr, left, right, ret)))
                    stk.append((1, (curr.right, right)))
                    stk.append((1, (curr.left, left)))
                elif step == 2:
                    curr, left, right, ret = args
                    d = -1
                    if curr.val == start:
                        d = 0
                        result = max(left[0], right[0])+1
                    elif left[1] >= 0:
                        d = left[1]+1
                        result = max(result, right[0]+1+d)
                    elif right[1] >= 0:
                        d = right[1]+1
                        result = max(result, left[0]+1+d)
                    ret[:] = [max(left[0], right[0])+1, d]  # [height, dist_to_start]
            return result

        return iter_dfs(root, start)


# Time:  O(n)
# Space: O(h)
# dfs, tree dp
class Solution2(object):
    def amountOfTime(self, root, start):
        """
        :type root: Optional[TreeNode]
        :type start: int
        :rtype: int
        """
        def dfs(curr, start, result):
            if curr is None:
                return [-1, -1]
            left = dfs(curr.left, start, result)
            right = dfs(curr.right, start, result)
            d = -1
            if curr.val == start:
                d = 0
                result[0] = max(left[0], right[0])+1
            elif left[1] >= 0:
                d = left[1]+1
                result[0] = max(result[0], right[0]+1+d)
            elif right[1] >= 0:
                d = right[1]+1
                result[0] = max(result[0], left[0]+1+d)
            return [max(left[0], right[0])+1, d]  # [height, dist_to_start]

        result = [-1]
        dfs(root, start, result)
        return result[0]


# Time:  O(n)
# Space: O(n)
# bfs
class Solution3(object):
    def amountOfTime(self, root, start):
        """
        :type root: Optional[TreeNode]
        :type start: int
        :rtype: int
        """
        def bfs(root):
            adj = collections.defaultdict(list)
            q = [root]
            while q:
                new_q = []
                for u in q:
                    for v in (u.left, u.right):
                        if v is None:
                            continue
                        adj[u.val].append(v.val)
                        adj[v.val].append(u.val)
                        new_q.append(v)
                q = new_q
            return adj

        def bfs2(adj, start):
            result = -1
            q = [start]
            lookup = {start}
            while q:
                new_q = []
                for u in q:
                    for v in adj[u]:
                        if v in lookup:
                            continue
                        lookup.add(v)
                        new_q.append(v)
                q = new_q
                result += 1
            return result

        adj = bfs(root)
        return bfs2(adj, start)

Solution from kamyu104/LeetCode-Solutions · MIT