124. Binary Tree Maximum Path Sum - 二叉樹中的最大路徑和

1 描述

給定一個非空二叉樹,返回其最大路徑和。node

路徑 : 一條從樹中任意節點出發,達到任意節點的序列。該路徑至少包含一個節點,且不必定通過根節點。bash

用例

輸入: [1,2,3]

       1
      / \
     2   3

輸出: 6
輸入: [-10,9,20,null,null,15,7]

   -10
   / \
  9  20
    /  \
   15   7

輸出: 42

解析

經過 &max 來記錄全局最大值,經過返回ret來記錄遞歸返回的值code

二叉樹 abc,a 是根結點(遞歸中的 root),bc 是左右子結點(表明其遞歸後的最優解)。
最大的路徑,可能的只有三種路徑狀況:blog

a
   / \
  b   c
  1. b + a + c。
  2. b + a + a父
  3. a + c + a父

其中狀況 1,表示若是不聯絡父結點的狀況,或自己是根結點的狀況。
這種狀況是無法遞歸的,可是結果有多是全局最大路徑和。
狀況 2 和 3,遞歸時計算 a+b 和 a+c,選擇一個更優的方案返回,也就是上面說的遞歸後的最優解啦。
另外結點有多是負值,最大和確定就要想辦法捨棄負值(max(0, x))(max(0,x))。遞歸

可是上面 3 種狀況,不管哪一種,a 做爲聯絡點,都不可以捨棄。three

暴力枚舉法

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int result = -2147483648;

int helper(struct TreeNode* root) {
    if (root == NULL) return 0; 
    int left = helper(root->left);
    int right = helper(root->right);
    int threeNodeSum = root->val + left + right;
    int twoNodeSum = root->val + max(left, right);
    int oneNodeSum = root->val;
    int ret = max(twoNodeSum, oneNodeSum);
    int currentMax = max(ret, threeNodeSum);
    result = max(currentMax, result);
    return ret;
}

int max(int a, int b) {
    return a > b ? a : b; 
}

int maxPathSum(struct TreeNode* root){
    result = -2147483648;
    int temp = helper(root);
    return result;
}

分析

#define max(a, b) ((a) > (b) ? (a) : (b))

int maxPath = INT_MIN;

int dfs(struct TreeNode *root) {
    if (root == NULL) {
        return 0;
    }

    // 左子樹的最大和
    int left = dfs(root->left);
    // 右子樹的最大和
    int right = dfs(root->right);
    // 當前節點路徑(不須要聯繫父結點,或自己就已是根結點而無父節點)的最大值 VS 當前全局最大值
    maxPath = max(left + right + root->val, maxPath);
    // 須要聯繫父節點,所以只返回子樹最大分支
    return max(0, max(left, right) + root->val);

}

int maxPathSum(struct TreeNode *root) {
    // 初始化爲最小可能的整數
    maxPath = INT_MIN;
    // 深度優先遍歷
    dfs(root);
    return maxPath;
}

相關文章
相關標籤/搜索