leetcode1372. 二叉树中的最长交错路径
给你一棵以 root 为根的二叉树,二叉树中的交错路径定义如下:
- 选择二叉树中 任意 节点和一个方向(左或者右)。
- 如果前进方向为右,那么移动到当前节点的的右子节点,否则移动到它的左子节点。
- 改变前进方向:左变右或者右变左。
- 重复第二步和第三步,直到你在树中无法继续移动。
- 交错路径的长度定义为:访问过的节点数目 - 1(单个节点的路径长度为 0 )。
请你返回给定树中最长 交错路径 的长度。
示例 1:
输入:root = [1,null,1,1,1,null,null,1,1,null,1,null,null,null,1,null,1]
输出:3
解释:蓝色节点为树中最长交错路径(右 -> 左 -> 右)。
思路一:暴力
对于每个节点,都有一个方法,找这个节点对应的最长交叉路径
class Solution {
public int longestZigZag(TreeNode root) {
if(root==null)return 0;
fun(root);
return maxLength-1;
}
//0-left,1-right
public int maxLength=0;
public void fun(TreeNode root){
if(root==null)return;
int left=traverse(root,0);
int right=traverse(root,1);
maxLength=Math.max(maxLength,Math.max(left,right));
fun(root.left);
fun(root.right);
}
public int traverse(TreeNode root,int direction){
if(root==null)return 0;
if(direction==0){
return traverse(root.left,1)+1;
}else{
return traverse(root.right,0)+1;
}
}
}
如果数据量太大就会超时.
思路二:
求最短路径的时候,会把当前节点走了多少步算出来,下一步的路径就可以用上一步的路径算,这样就不用从头累加计算了.
根据这个思路,cur表示节点个数,maxLength是最大值.对于每个节点,如果满足交叉路径的条件,那么cur+1,否则cur从2开始.
然后是遍历,在遍历的时候如果满足交叉路径就维持cur+1,否则cur要重新计数.
class Solution {
public int longestZigZag(TreeNode root) {
if(root==null)return 0;
traverse(root,0,1);
return maxLength-1;
}
//0-left,1-right
public int maxLength=0;
public void traverse(TreeNode root,int lastDirection,int cur){
//lastDirection表示当前节点是上一个节点的左还是右节点
if(root==null){
maxLength=Math.max(cur-1,maxLength);
//cur-1是因为当前节点为空
return;
}
if(lastDirection==0){
traverse(root.right,1,cur+1);//满足交叉
traverse(root.left,0,2);//重新计算节点个数
//2是因为自己当前节点,加上下一个节点,如果为空,在return处理
}else{
traverse(root.left,0,cur+1);
traverse(root.right,1,2);
}
}
}
这样就只用遍历n个节点,复杂度是log(n).
leetcode 54/100