【题目描述】
【代码思路】
最近在做深度优先的特辑,同样是递归的还有我之前的leetcode 695--岛屿的最大面积 和 leetcode 872--叶子相似的树,
这道题我走了一些弯路,因为理解错了题干,先看下面一个图,
在我理解错误的时候,以为是只要递归的求每个结点的最长左子树同值长度与最长右子树之和就可以,那么上图的最长同值路径是从根结点26开始连接在一起同值的结点有6个,路径也就是5,但答案为4,说明题干要求的最长路径是单向传递的,不能回溯,也就是不能倒着往回连,因此需要改变思路。 递归函数return的结果应该是左右子树中最长同值路径中较大值返回给父结点,而不是把左右子树之和返回给父结点。就像我之前说的,要想弄清递归函数内部逻辑,要抓住一个点来分析,拿下面这颗树来说:
首先我们需要一个全局变量cmax来存储最长同值路径,不断对比更新cmax,我们就看4这个结点,递归函数名为dfs(root),想获得4结点的最长同值路径,先获得它左子树的最长同值路径left,再获得它右子树的最长同值路径right,
然后再判断父结点与左右子树根结点值是否一致,看left和right是否要+1还是置0,如果左子树不为空,且左子树值与父结点相同,则可以加上父结点到左子结点的这条边,即left+1,否则,如果父子值不等,那么左子树的最长路径对于父结点无意义,因为不能连接到一起,所以置为0。右子树同理。
最后更新cmax=max(left+right,cmax),但是返回给上层的是max(left,right),因为不能回溯,所以不能返回左右之和。如果dfs(root==NULL),对于空结点肯定是return 0,都不需要执行下面的语句了;
【源代码】
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int current_max=0;
int longestUnivaluePath(TreeNode* root) {
dfs(root);
return current_max;
}
int dfs(TreeNode* root){
if(root==NULL){
return 0;
}
int left=dfs(root->left);
int right=dfs(root->right);
if(root->left!=NULL&&root->val==root->left->val){
left+=1;
}else{
left=0;
}
if(root->right!=NULL&&root->val==root->right->val){
right+=1;
}else{
right=0;
}
current_max=max(current_max,left+right);
return max(left,right);
}
};