给你一棵具有唯一值的二叉树的根节点和一个整数起点。第 0 分钟时,感染从值为 start 的节点开始。
在下列情况下,每分钟都会感染一个节点:
返回整棵树被感染所需的分钟数。
Example 1:
Input: root = [1,5,3,null,4,10,6,9,2], start = 3 Output: 4 Explanation: The following nodes are infected during: - Minute 0: Node 3 - Minute 1: Nodes 1, 10 and 6 - Minute 2: Node 5 - Minute 3: Node 4 - Minute 4: Nodes 9 and 2 It takes 4 minutes for the whole tree to be infected so we return 4.
Example 2:
Input: root = [1], start = 1 Output: 0 Explanation: At minute 0, the only node in the tree is infected so we return 0.
树内的节点都是不重复的。因此我们只需要找到起始节点到根节点的最远距离就是结果。两条提示:
BFS简单,问题是如何从起始节点开始?如果具有初始值的节点刚好是根节点,那么题目就变成了与根节点的最大距离,也就是树的最大深度。
那么问题就转变成了,能否有一种方法,即使起始节点不是根节点,也能利用子树深度计算出起始节点的最大距离?
我们需要解决的第一个问题是:能否使用子树的深度来确定起始节点的最大距离?
这项任务的一个难点是识别我们是否在遍历过程中遇到了起始节点。我们可以在遇到起始节点时返回负深度。这将标志着我们已经找到了起始节点,当我们遍历树时,只要遇到负深度,我们就知道子树包含起始节点。
此外,在遍历树的过程中,我们可能会在计算出树的每个部分的最大深度之前就找到起始节点。因此,我们需要保存最大距离,并在遍历树的其他部分时继续计算它。
思路的核心在于如何处理起始节点。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int maxDistance = 0;
int traversal(TreeNode* root, int start) {
int depth = 0;
if (root == nullptr) {
return depth;
}
int leftDepth = traversal(root->left, start);
int rightDepth = traversal(root->right, start);
if (root->val == start) {
maxDistance = max(leftDepth, rightDepth);
depth = -1;
} else if (leftDepth >= 0 && rightDepth >= 0) {
depth = max(leftDepth, rightDepth) + 1;
} else {
int distance = abs(leftDepth) + abs(rightDepth);
maxDistance = max(maxDistance, distance);
depth = min(leftDepth, rightDepth) - 1;
}
return depth;
}
int amountOfTime(TreeNode* root, int start) {
traversal(root, start);
return maxDistance;
}
};
Time complexity:?O(n)
Traversing the tree with a DFS costs?O(n)O(n)O(n)?as we visit each node exactly once.
Space complexity:?O(n)
lc的题解,我也没太理解,再想想。