LC每日一题|20240424 - 2385. 感染二叉树需要的总时间
给你一棵二叉树的根节点
root
,二叉树中节点的值 互不相同 。另给你一个整数start
。在第0
分钟,感染 将会从值为start
的节点开始爆发。每分钟,如果节点满足以下全部条件,就会被感染:
- 节点此前还没有感染。
- 节点与一个已感染节点相邻。
返回感染整棵树需要的分钟数 。
提示:
- 树中节点的数目在范围
[1, 10^5]
内 1 <= Node.val <= 10^5
- 每个节点的值 互不相同
- 树中必定存在值为
start
的节点
题目等级:Medium
解题思路
不难发现此题的难点是在如何处理 start
节点的 parents
。我们首先可以找到 start
节点,然后记录它的 parent
节点们到它的距离
,显然dfs是更适合需求的方案。对于其他的节点,我们可以先定义距离为无歧义的 -1
,待下一次遍历时进行处理。
由于题目并没有要求我们不能改动树,所以我们可以将这个距离值保存在root.val
中。
下一步,我们可以使用bfs再次遍历整棵树。对于上一步中未处理的节点,其距离值为其父节点的距离值+1。然后在遍历的过程中统计最大值返回。
AC代码
/**
* Example:
* var ti = TreeNode(5)
* var v = ti.`val`
* Definition for a binary tree node.
* class TreeNode(var `val`: Int) {
* var left: TreeNode? = null
* var right: TreeNode? = null
* }
*/
class Solution {
fun amountOfTime(root: TreeNode, start: Int): Int {
dfs(root, start)
var max = root.`val`
val queue = ArrayDeque<TreeNode>()
queue.addLast(root)
while (queue.isNotEmpty()) {
repeat(queue.size) {
val node = queue.removeFirst()
node.left?.let {
if (it.`val` == -1) it.`val` = node.`val` + 1
max = Math.max(it.`val`, max)
queue.addLast(it)
}
node.right?.let {
if (it.`val` == -1) it.`val` = node.`val` + 1
max = Math.max(it.`val`, max)
queue.addLast(it)
}
}
}
return max
}
fun dfs(root: TreeNode?, target: Int): Int {
if (root == null) return -1
val left = dfs(root.left, target)
val right = dfs(root.right, target)
root.`val` = if (root.`val` == target) 0 else if (left >= 0 || right >= 0) Math.max(left, right) + 1 else -1
return root.`val`
}
}
时间复杂度:O(n)
,需要两次遍历。
空间复杂度:O(n)
。