题目20:1372. 二叉树中的最长交错路径
同类题目
前置知识
- 无
题目描述
-
给你一棵以
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]之间。
思路分析
记录当前结点是左/右孩子,即记录当前路径的方向,搜索其孩子时,根据上一条路径方向判断,如果当前路径方向相反,路径长度+1,如果相同,路径长度置为1。
程序代码
方法一:
// https://leetcode.cn/problems/longest-zigzag-path-in-a-binary-tree/description/
// 1372. 二叉树中的最长交错路径
#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
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 {
private:
// 全局变量
int mx = 0;
public:
void cal(TreeNode *root,int dir,int nowmx)
{
if(root == nullptr)
{
return;
}
mx = max(mx,nowmx);
// 往左走
if(dir == 1)
{
// 往右走并且路径+1,因为root 已经算一个
cal(root->right,2,nowmx+1);
// 往左走的化,就从1开始记录
cal(root->left,1,1);
}
// 往右走
if(dir == 2)
{
// 往左走并且路径+1,因为root 已经算一个
cal(root->left,1,nowmx+1);
// 往右走的化,就从1开始记录
cal(root->right,2,1);
}
}
int longestZigZag(TreeNode* root) {
if(root == nullptr)
{
return 0;
}
// 往左子树用1来标记,忘右子树用2,根节点左右都可以走
cal(root,1,0);
cal(root,2,0);
return mx;
}
};
复杂度分析
时间复杂度:最坏情况下需要对所有节点进行匹配。假设一共有 n个节点,最坏情况下每次匹配均为到链表的最后一个节点的时候匹配失败,那么一共被匹配到的节点数为2^(len+1)-1 ,即这个节点为根的子树往下len层的满二叉树的节点数,其中len为链表的长度,而二叉树总节点数最多n个,所以枚举节点最多匹配min(2^(len+1),n)次,最坏情况下需要O(n∗min(2^(len+1),n))的时间复杂度。
空间复杂度:O(logN) ,其中logN 为二叉树的高度。
题目感悟
双重dfs 第一次使用,不是很熟练,后续会重点练习一下。
更多相关知识:github.com/pingguo1987…