zoukankan      html  css  js  c++  java
  • 【LeetCode-树】二叉树中的最大路径和

    题目描述

    给定一个非空二叉树,返回其最大路径和。
    本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
    示例:

    输入: [1,2,3]
    
           1
          / 
         2   3
    输出: 6
    
    输入: [-10,9,20,null,null,15,7]
       -10
       / 
      9  20
        /  
       15   7
    输出: 42
    

    题目链接: https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/

    思路

    使用递归来做。需要注意的是:

    • 路径不一定通过根节点;
    • 路径不一定经过叶子节点;
    • 路径最少可以只包含 1 个节点;

    因为不一定通过根节点,所以遍历整棵树,将当前节点作为根节点求解并记录路径的最大值。代码如下:

    /**
     * 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 maxPathSum(TreeNode* root) {
            if(root==nullptr) return 0;
    
            queue<TreeNode*> q;
            q.push(root);
            int curMax = INT_MIN;
            while(!q.empty()){
                TreeNode* node = q.front(); q.pop();
                int level = 0;
                curMax = max(curMax, dfs(node, level));
                curMax = max(curMax, node->val); // 可能只包含一个节点
                if(node->left!=nullptr) q.push(node->left);
                if(node->right!=nullptr) q.push(node->right);
            }
            return curMax;
        }
    
        int dfs(TreeNode* root, int level){
            if(root==nullptr) return 0;
            if(root->left==nullptr && root->right==nullptr) return root->val;
            
            if(level==0){
                int leftLen = dfs(root->left, level+1); // 根节点左子树的长度
                int rightLen = dfs(root->right, level+1);  // 根节点右子树的长度
                int len1 = root->val + leftLen;  // 根节点+左子树的长度
                int len2 = root->val + rightLen;  // 根节点+右子树的长度
                int len3 = root->val + leftLen + rightLen;  // 根节点+左子树+右子树的长度
                return max(max(len1, len2), len3); // 返回 3 个长度的最大值
            }else{
                /*返回当前根节点和当前根节点与左右子树路径最大值之和的最大值,因为不一定通过叶子节点*/
                return max(root->val, root->val + max(dfs(root->left, level+1), dfs(root->right, level+1)));
            }
        }
    };
    

    其中的 level 表示当前的层数。如果当前是第一层(level==0,根节点)那么就要求 3 个长度的最大值;如果不在第一层,则求左右子树的最大值就行了,因为最多只能走左子树或者右子树,不会两边都走。

    简化写法

    /**
     * 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 {
        int ans = INT_MIN;
    public:
        int maxPathSum(TreeNode* root) {
            if(root==nullptr) return 0;
            dfs(root);
            return ans;
        }
    
        int dfs(TreeNode* root){
            if(root==nullptr) return 0;
    
            //计算左边分支最大值,左边分支如果为负数还不如不选择
            int leftMax = max(0, dfs(root->left));
    
            //计算右边分支最大值,右边分支如果为负数还不如不选择
            int rightMax = max(0, dfs(root->right));
    
            //left->root->right 作为路径与历史最大值做比较
            ans = max(ans, root->val+leftMax+rightMax);
    
            // 返回经过root的单边最大分支给上游
            return root->val + max(leftMax, rightMax);
        }
    };
    

    参考

    简化写法参考了:https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/solution/er-cha-shu-zhong-de-zui-da-lu-jing-he-by-ikaruga/313184

  • 相关阅读:
    解决:IIS APPPOOLDefaultAppPool 登录失败的问题
    C#操作txt文件并清空添加操作
    linux修改yum本地源的方法
    CentOS防火墙开启、关闭与开放指定端口
    CentOS配置SSH远程连接
    判断js对象是否拥有某一个属性的js代码
    bash脚本输入密码不回显问题的解决方法
    js控制表单操作的常用代码小结
    绝版Node--Sequlize搭建服务(Node全栈之路 二)
    绝版Node--Sequlize搭建服务(Node全栈之路)
  • 原文地址:https://www.cnblogs.com/flix/p/13172954.html
Copyright © 2011-2022 走看看