二叉树中的最长交错路径
难度:
标签:
题目描述
给你一棵以 root
为根的二叉树,二叉树中的交错路径定义如下:
- 选择二叉树中 任意 节点和一个方向(左或者右)。
- 如果前进方向为右,那么移动到当前节点的的右子节点,否则移动到它的左子节点。
- 改变前进方向:左变右或者右变左。
- 重复第二步和第三步,直到你在树中无法继续移动。
交错路径的长度定义为:访问过的节点数目 - 1(单个节点的路径长度为 0 )。
请你返回给定树中最长 交错路径 的长度。
示例 1:
输入:root = [1,null,1,1,1,null,null,1,1,null,1,null,null,null,1,null,1] 输出:3 解释:蓝色节点为树中最长交错路径(右 -> 左 -> 右)。
示例 2:
输入:root = [1,1,1,null,1,null,null,1,1,null,1] 输出:4 解释:蓝色节点为树中最长交错路径(左 -> 右 -> 左 -> 右)。
示例 3:
输入:root = [1] 输出:0
提示:
- 每棵树最多有
50000
个节点。 - 每个节点的值在
[1, 100]
之间。
代码结果
运行时间: 348 ms, 内存: 61.5 MB
/*
* 思路:
* 1. 使用递归和Stream API遍历二叉树。
* 2. 在每个节点上使用Stream遍历其左右子树并计算最长交错路径。
* 3. 使用IntStream来计算每个方向的最大长度。
*/
import java.util.stream.IntStream;
class Solution {
public int longestZigZag(TreeNode root) {
return IntStream.of(dfs(root.left, false, 1), dfs(root.right, true, 1)).max().orElse(0) - 1;
}
private int dfs(TreeNode node, boolean isRight, int length) {
if (node == null) return length - 1;
return isRight ?
Math.max(dfs(node.left, false, length + 1), dfs(node.right, true, 1)) :
Math.max(dfs(node.right, true, length + 1), dfs(node.left, false, 1));
}
}
解释
方法:
本题解采用了深度优先搜索(DFS)的方法来解决二叉树的最长交错路径问题。首先定义一个全局变量 `longest` 来存储目前找到的最长路径长度。接着,定义一个递归函数 `dfs` 来探索每个节点,该函数接受当前节点、当前路径的长度 `depth`,以及一个布尔值 `isLeft` 指示当前的方向(左或右)。函数中,首先更新 `longest` 为当前路径长度和 `longest` 的较大值。如果当前节点为 `None`,则直接返回。根据当前的方向,递归调用左子或右子节点,并调换方向。最后,从根节点的左子和右子开始分别调用 `dfs` 函数,初始化方向分别为左和右,以探索所有可能的交错路径。最终,返回 `longest` 作为结果。
时间复杂度:
O(n)
空间复杂度:
O(h)
代码细节讲解
🦆
为什么在递归函数中,当改变方向时,路径长度depth要增加,但重新开始一个方向时,depth却重置为0?
▷🦆
在递归过程中,对于没有子节点的叶子节点,函数如何处理,它是否会影响最长路径的计算?
▷🦆
您提到使用了全局变量`longest`来记录最长路径长度,这种方法在多线程环境下是否会引发问题,如果会,有什么替代方案?
▷🦆
递归函数`dfs`没有返回任何值,这是基于什么考虑?是否有可能通过返回值来优化代码的执行效率?
▷