2385. 感染二叉树需要的总时间

175 阅读2分钟

题目:
给你一棵二叉树的根节点 root ,二叉树中节点的值 互不相同 。另给你一个整数 start 。在第 0 分钟,感染 将会从值为 start 的节点开始爆发。

每分钟,如果节点满足以下全部条件,就会被感染:

  • 节点此前还没有感染。
  • 节点与一个已感染节点相邻。

返回感染整棵树需要的分钟数
算法:
方法一:树形DP
是个模板题。学到了树形DP的模板

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func amountOfTime(root *TreeNode, start int) int {
    var target *TreeNode
    parent := make(map[*TreeNode]*TreeNode, 0)
    var findParent func(node *TreeNode)
    findParent =  func(node *TreeNode) {
        if node == nil {
            return 
        }
        if node.Val == start {
            target = node
        }
        if node.Left != nil {
            parent[node.Left] = node
            findParent(node.Left)
        }
        if node.Right != nil {
            parent[node.Right] = node
            findParent(node.Right)
        }
    }
    findParent(root)

    // 从node节点开始搜索,找到到叶子节点或者start节点的停止,返回搜索的最大深度
    var dfs func(node, from *TreeNode, step int) 
    ans := 0
    dfs = func(node, from *TreeNode, step int) {
        if node == nil {
            return
        }
        ans = max(ans, step)
        if node.Left != from {
            dfs(node.Left, node, step + 1)
        }
        if node.Right != from {
            dfs(node.Right, node, step + 1)
        }
        if parent[node] != from {
            dfs(parent[node], node, step + 1)
        }
    }
    dfs(target, nil, 0)
    return ans
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

方法二: DFS + BFS

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func amountOfTime(root *TreeNode, start int) int {
    var target *TreeNode
    parent := make(map[*TreeNode]*TreeNode, 0)
    var findParent func(node *TreeNode)
    findParent =  func(node *TreeNode) {
        if node == nil {
            return 
        }
        if node.Val == start {
            target = node
        }
        if node.Left != nil {
            parent[node.Left] = node
            findParent(node.Left)
        }
        if node.Right != nil {
            parent[node.Right] = node
            findParent(node.Right)
        }
    }
    findParent(root)
    queue := []*TreeNode{target}
    visited := make(map[*TreeNode]bool)
    visited[target] = true
    // 从node节点开始搜索,找到到叶子节点或者start节点的停止,返回搜索的最大深度

    ans := -1
    for len(queue) > 0 {
        n := len(queue)
        for i := 0; i < n; i ++ {
            if queue[i].Left != nil && !visited[queue[i].Left] {
                queue = append(queue, queue[i].Left)
                visited[queue[i].Left] = true
            }
            if queue[i].Right != nil && !visited[queue[i].Right] {
                queue = append(queue, queue[i].Right)
                visited[queue[i].Right] = true
            }
            if parent[queue[i]] != nil && !visited[parent[queue[i]]] {
                queue = append(queue, parent[queue[i]])
                visited[parent[queue[i]]] = true
            }
        }
        queue = queue[n:]
        ans ++
    }

    return ans
}