天天看點

leetcode華為面試算法題-124. 二叉樹中的最大路徑和

作者:程式員的交流電
leetcode華為面試算法題-124. 二叉樹中的最大路徑和
leetcode華為面試算法題-124. 二叉樹中的最大路徑和

之前華為面試的是遇到了讓求二叉樹最大路徑和,讓說一下大緻的思路,當時這道題目成功的通過了。這裡我來詳細歸納整理一下對應思路。

求最值的問題基本上都有一個通用的解法,那就是暴力,如果我們在解題的時候沒有更好的思路,最終可能要嘗試暴力的解法,畢竟“你能做出來,和你什麼都不做”是有很大的差别的。

求最值的問題我的第一反應是動态規劃,動态規劃主要就是用于求最值的問題,但是這裡的題目是二叉樹,二叉樹通常的解法是遞歸,基本所有的二叉樹類的問題都是可以通過遞歸架構來解決的,然後需要根據情況來判斷是前序中序後序等不同的周遊。下面寫的就是一個正常的遞歸架構。

void traverse(TreeNode node) {
 // 前序周遊
 traverse(node.left);
 // 中序周遊
 traverse(node.right);
 // 後序周遊
}           

是以到這裡,首先基本上你要确定你的算法思路,不同類型的問題通常有其正常對應的解法,這裡我就打算使用樹的遞歸來解決問題,整體思路确定了,下面就是按照這個思路架構來套,寫出對應的代碼。

public int maxPathSum(TreeNode root) {
 int traverse = traverse(root);
 return Math.max(traverse,maxValue);
}

public int maxValue = Integer.MIN_VALUE;

public int traverse(TreeNode root) {
 if (root == null ) {
 return 0;
 }
 // 左子樹的最大路徑,必須要大于0
 int left = Math.max(traverse(root.left),0);
 // 右子樹的最大路徑,必須要大于0
 int right = Math.max(traverse(root.right),0);

 // 目前節點連接配接左右子樹形成的最大路徑
 maxValue = Math.max(maxValue, root.val + left + right);
 // 目前節點和左子樹或者和右子樹連接配接取最大值
 return Math.max(root.val + left, root.val + right);
}           

執行結果

leetcode華為面試算法題-124. 二叉樹中的最大路徑和

這題的解法使用的正常的樹的遞歸,然後使用後序周遊的架構,但需要注意的是,要考慮一些邏輯細節,比如說左右子樹如果小于0了,這個時候目前節點應該舍去小于0的左右子樹。

總結起來有三種邏輯:

  • 目前節點和左子樹連接配接
  • 目前節點和右子樹連接配接
  • 目前節點和左右子樹連接配接。

總結一下,求最值的問題,一般都是有最優子結構的,這裡的traverse(root.left)其實就是要求出左子樹的最優子結構,我們常在動态規劃中看到最優子結構的,它是一類求最值問題的特性,并不是動态規劃特有的。