687. 最长同值路径【中】
思路1:深度优先
最长path长度总会是以一个节点加上其 同值左子树 和 同值右子树 的同值路径长度。
1、维护一个maxpath记录最长同值路径长度
2、使用dfs找到 和当前node结点同值 左子树和右子树 中 的最长path,因为返回给上一层,只能是其中一条最长的路径长度。
3、dfs里当左孩子不为空,且左同值,则进入dfs,否则左子树同值path最长为0。
代码:
class Solution {
public:
int maxpath = 0;
int longestUnivaluePath(TreeNode* root) {
dfs(root);
return maxpath;
}
// 找node结点左子树或右子树的最长path
int dfs(TreeNode* node){
if (!node) return 0;
int left = 0,right = 0;
//如果左子树非空,且左子树val等于当前结点val
if(node->left){
if(node->left->val == node->val)
//左边的path长为 左子树最长的子树path
left = dfs(node->left)+1;
}
if(node->right){
if(node->right->val == node->val)
right = dfs(node->right)+1;
}
// 左子path+右子path对比
maxpath = max(maxpath,left+right);
// 返回最长的子path
return max(right,left);
}
};
按照这样的思路撰写代码,有一个例子无法通过。且这个例子平平无奇,并不像是出题人故意捣乱。
然后发现一个自己代码有个特别严重的问题。我的递归调用被放在了条件里,使得当条件语句不满足的时候,不能进入下一次的递归,就会缺失问题。如:左孩子非同值时,将不会进入dfs进入左子树。
if(node->left){
if(node->left->val == node->val)
//左边的path长为 左子树最长的子树path
left = dfs(node->left)+1;
}
重新修改代码:
//s:O(n) t:O(n)
class Solution {
public:
int maxpath = 0;
int longestUnivaluePath(TreeNode* root) {
dfs(root);
return maxpath;
}
int dfs(TreeNode* node){
if(!node) return 0;
int left = 0, right = 0;
// 先进行递归 再进行计算 其实就是后序遍历的思想!!
int leftpath = dfs(node->left),rightpath = dfs(node->right);
if(node->left && node->left->val == node->val) left = leftpath + 1;
if(node->right && node->right->val == node->val) right = rightpath + 1;
maxpath = max(maxpath,left+right);
return max(left,right);
}
};