Woodyiiiiiii / LeetCode

My private record of Leetcode solution

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Leetcode 2385. Amount of Time for Binary Tree to Be Infected

Woodyiiiiiii opened this issue · comments

这题我花了一个多小时才写出来,花了很多时间,同时感觉这题也很有意思,所以记录一下。

一开始我看有点像树的path题型,所以试图使用后序遍历/DFS,然后发现不太对,转变了思路其实应该继续深究;然后我接着想把树分段计算路径,以start节点分成几段计算路径和,写了一大堆函数和分类讨论,最后发现思路错了,因为发现无法分段,假如有树在start节点之上有很多分支,比如"人"上还有“人”,这样无法计算;最后我只能重新回归初始的DFS想法,做了出来。

这道题本质上还是DFS,需要思考的是如何计算ans和返回值,需要一点分类讨论。有一点小技巧:

  1. 用数组作为返回值,标记
  2. 每次循环计算结果ans,全局变量
class Solution {

    int ans = 0;

    public int amountOfTime(TreeNode root, int start) {
        // postorder
        dfs(root, start);
        return ans;
    }

    // the return: a[0] means the path, a[1] means if it passes through the node of start
    private int[] dfs(TreeNode root, int start) {
        if (root == null) return new int[]{0, 0};
        int[] left = dfs(root.left, start);
        int[] right = dfs(root.right, start);
        // isLeft means the left subtree contains the start node, isRight means the right ...
        boolean isLeft = false, isRight = false;

        if (left[1] == 1 || right[1] == 1) {
            // calculate the sum of path from start node to the most distant node
            ans = Math.max(ans, left[0] + right[0] + 1);
            isLeft = left[1] == 1;
            isRight = right[1] == 1;
        } else {
            // the left and right path does not contain the start node
            ans = root.val == start ? Math.max(ans, Math.max(left[0], right[0])) : Math.max(ans, Math.max(left[0], right[0]) + 1);
        }
        
        // calculate the return arry
        return root.val == start ? new int[]{0, 1} : ((!isLeft && !isRight) ? new int[]{Math.max(left[0], right[0]) + 1, 0} :
                new int[]{isLeft ? left[0] + 1 : right[0] + 1, 1});
    }
}