树的路径和总结:【leetcode124,543,2246】

解题思路

一棵保存信息的树如何去递归?

  • 分析单独的子树要进行什么操作
  • 分析这颗子树要返回什么东西

参考b站讲解:leetcode最热门100题

示例
1、二叉树的直径

  • 每一棵子树的直径是其子树+1
  • 返回的当前结点的直径(左边的直径和右边的直径取最大)

2、二叉树的最大路径和

  • 每一棵子树的路径和max(左孩子路径和,有孩子路径和)+根节点的值,如果左孩子或者有孩子路径和为负数,则直接砍掉不要
  • 返回当前子树的最大路径和

代码如下

leetcode543二叉树的直径
在这里插入图片描述

class Solution {
public:
    int ans = 0;
    int dfs(TreeNode* root) {
        if(!root)return -1;
        int l = dfs(root->left) + 1;
        int r = dfs(root->right) + 1;
        ans = max(ans, l + r);
        return max(l,r);
    }
    int diameterOfBinaryTree(TreeNode* root) {
        dfs(root);
        return ans;
    }
};

二叉树中的最大路径和
在这里插入图片描述


class Solution {
public:
    int ans;
    int dfs(TreeNode* root){
        if(!root)return 0;
        //计算左子树
        int l = dfs(root->left);
        if(l < 0)l = 0;//如果小于0就直接砍掉
        //计算右子树
        int r = dfs(root->right);
        if(r < 0)r = 0;
        ans = max(ans,l + r + root->val);
        //对于这棵子树的返回
        return max(l + root->val,r + root->val);
    }
    int maxPathSum(TreeNode* root) {
        ans = INT_MIN;
        dfs(root);
        return ans;
    }
};

相邻字符不同的最长路径
在这里插入图片描述

解题思路

1、每一棵子树需要去做什么?

  • 如果符合条件,当前树的路径长 = 子树的路径长+1

2、当前这棵树返回的是什么?

  • 返回的是当前树的最长路径=所有符合条件的子树中的最长路径
  • maxLen = max(maxLen,len + 1);//挑选最长的子树
class Solution {
public:
    int longestPath(vector<int>& par, string s) {
        int n = par.size();
        vector<vector<int>> g(n);//保存的是每个结点的子节点是什么
        for(int i = 1; i < n; ++i) {
            g[par[i]].push_back(i);
        }
        int ans = 1;
        function<int(int)> dfs = [&](int u)->int {
            int maxLen = 1;//如果是叶子节点就返回1
            for (int y : g[u]) {
                int len = dfs(y);//子树的路径长度
                if (s[y] != s[u]) {//只有不相等的时候才更新路径长度
                    ans = max(ans,maxLen + len);//如果当前就是答案,保存答案
                    maxLen = max(maxLen,len + 1);//挑选最长的子树
                }
            }
            return maxLen;//返回的是当前树的路径长度
        };
        dfs(0);
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值