Leetcode 2385. Amount of Time for Binary Tree to Be Infected
Woodyiiiiiii opened this issue · comments
这题我花了一个多小时才写出来,花了很多时间,同时感觉这题也很有意思,所以记录一下。
一开始我看有点像树的path题型,所以试图使用后序遍历/DFS,然后发现不太对,转变了思路其实应该继续深究;然后我接着想把树分段计算路径,以start节点分成几段计算路径和,写了一大堆函数和分类讨论,最后发现思路错了,因为发现无法分段,假如有树在start节点之上有很多分支,比如"人"上还有“人”,这样无法计算;最后我只能重新回归初始的DFS想法,做了出来。
这道题本质上还是DFS,需要思考的是如何计算ans和返回值,需要一点分类讨论。有一点小技巧:
- 用数组作为返回值,标记
- 每次循环计算结果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});
}
}