赞
踩
题目来源:https://leetcode.cn/problems/amount-of-time-for-binary-tree-to-be-infected/
大致题意:
给一个二叉树和一个节点,假设该节点每单位时间可以感染与其相邻的节点,被感染的节点之后也会感染相邻节点,求整颗二叉树被感染需要的时间。
相邻节点是指某个节点的子节点和父节点
比较简单的方法是:
但是该方法需要额外的空间来存储父节点,可以分析该问题得到该二叉树被感染的时间的计算方式:
在未找到目标节点时,可以认为某个节点感染其子节点的时间即为距离
于是可以通过 bfs 遍历求得上述所有感染时间的最大值即为答案,具体搜索时可以使用一个标志位存下目标节点所在层,同时每次遍历是标记当前节点所在层,这样当找到目标节点时,即可通过层数之间的差求得目标节点和祖先节点之间的感染时间。对于目标节点不在当前节点子树的情况,因为有标志位判断的情况存在,若此时目标节点已找到,相等于目标节点在左子树的情况(但是当前结果不会对答案有贡献,只是免去了特殊处理),否则不做特殊处理。
具体看代码:
class Solution { int ans; // 二叉树被感染的时间 int startDepth; // 目标节点所在层 int start; // 目标节点值 public int amountOfTime(TreeNode root, int start) { ans = 0; startDepth = -1; // 初始化为 -1,表示未找到目标节点 this.start = start; dfs(root, 0); return ans; } public int dfs(TreeNode node, int depth) { if (node == null) { return 0; } // 当前节点左子树的最大深度 int l = dfs(node.left, depth + 1); // 如果此时目标节点已找到,说明目标节点在左子树中 boolean inLeft = startDepth != -1; // 当前节点右子树的最大深度 int r = dfs(node.right, depth + 1); // 如果此时目标节点找到,说明目标节点在右子树中 boolean inRight = !inLeft && startDepth != -1; // 若当前节点为目标节点,更新目标节点深度和答案 if (node.val == start) { startDepth = depth; ans = Math.max(Math.max(l, r), ans); } else if (inLeft) { // 在左子树中,更新答案 ans = Math.max(startDepth - depth + r, ans); } else if (inRight) { // 在右子树中,更新答案 ans = Math.max(startDepth - depth + l, ans); } return Math.max(l, r) + 1; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。