題目地址:
https://leetcode-cn.com/probl...
題目描述:
給定一個非空二叉樹,返回其最大路徑和。 本題中,路徑被定義為一條從樹中任意節(jié)點出發(fā),達到任意節(jié)點的序列。該路徑至少包含一個節(jié)點,且不一定經(jīng)過根節(jié)點。 示例 1: 輸入: [1,2,3] 1 / 2 3 輸出: 6 示例 2: 輸入: [-10,9,20,null,null,15,7] -10 / 9 20 / 15 7 輸出: 42
解答:
這一題,看上去,根本不可能做出來!為什么呢?因為這里的路徑和很特別,它可以是從任意點到任意點的路徑,搜索我都搜索不出來,按照定義路徑可以是從一個葉子到另一個葉子,比如這樣:
-10 / 9 20 / 15 7
15->20->7,這條路徑,怎么搜索?搜索的代碼都寫不出來!!!
那么只能放棄了。。。
我認為直接求路徑和這題是無解的,寫不出代碼。而這一題我是求別的東西,順帶求出了答案。
但是想一下下面的幾個簡單問題,這個問題就能做出來了!
(如果跳過這幾個簡單問題直接看答案,除非你天賦異稟,否則能看懂那你這思維也是沒誰了)
二叉樹的深度怎么求?
int depth(TreeNode root) { if(root == null)return 0; return 1+Math.max(depth(root.left),depth(root.right)); }
二叉樹的深度等于,max(左子樹的深度,右子樹的深度)+1。
假設(shè)二叉樹的val字段為int類型。
基于求深度的思想,進階一下求根節(jié)點到葉節(jié)點的最大路徑和:
int maxSum(TreeNode root) { if(root == null)return 0; return root.val + Math.max(maxSum(root.left),maxSum(root.right)); }
根到葉的最大路徑和等于max(左子樹根到葉最大路徑和,右子樹根到葉最大路徑和)+root.val。
現(xiàn)在求,根節(jié)點到某一子節(jié)點,使得該路徑和最大,該子節(jié)點可以不是葉子節(jié)點,給出最大路徑長度。
how?
這個和上面那倆其實是一個原理,給這個函數(shù)起個名字叫做"根向下最大延申"
那么算法是:
int temp =max(左子樹根向下最大延申,右子樹根向下最大延申)。
若temp > 0,則根向下最大延申=root.val+temp,否則根向下最大延申=root.val
代碼為:
int dfs(TreeNode root) { if(root == null)return 0; int left = dfs(root.left); int right = dfs(root.right); int temp = Math.max(left,right); if(temp > 0) temp += root.val; else temp = root.val; return temp; }
求出上面這個有什么用!!!???用處實在是太大了啊啊啊啊啊!!!!!
求出了上面這個,這個問題就基本可解了!!!
為什么呢?
我們這么想,給我任意一個樹的節(jié)點root,現(xiàn)在給這個"根向下最大延申"函數(shù)起個英文名叫做dfs。那么經(jīng)過這個節(jié)點的最大路徑和只可能是下面幾種情況:
1、
root.val
該節(jié)點本身值。
2、
dfs(root.left)+root.val,該節(jié)點本身值+左子樹向下最大延申。
此時dfs(root.left) > 0 && dfs(root.right) <= 0。
3、
dfs(root.right)+root.val,該節(jié)點本身值+右子樹向下最大延申。
此時dfs(root.left) <= 0 && dfs(root.right) > 0。
4、dfs(root.left)+dfs(root.right)+root.val
該節(jié)點本身值+左右子樹向下最大延申。
此時dfs(root.left) > 0 && dfs(root.right) > 0。
上面四種情況包含了經(jīng)過這個節(jié)點的最大路徑和的所有可能。
雖然不能求出任意點到任意點的路徑和,但是已經(jīng)可以得到該題的解了!!!
(讀者可以想想為什么不求出任意點到任意點的路徑和也能求出答案)
因此,對于任意一個節(jié)點root,求出經(jīng)過該節(jié)點的最大路徑和,然后和全局答案
進行比較,更新全局答案為最大值,就能夠求出這一題的答案!!!
java ac代碼:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public int maxPathSum(TreeNode root) { if(root == null)return 0; dfs(root); return ans; } int ans = Integer.MIN_VALUE; //求該點能向下延申的最大值 int dfs(TreeNode root) { if(root == null)return 0; int left = dfs(root.left); int right = dfs(root.right); int temp = Math.max(left,right); if(temp > 0) temp += root.val; else temp = root.val; int val = root.val; if(left >= 0)val += left; if(right >= 0)val += right; ans = Math.max(ans,val); return temp; } }
Amazing!!!
代碼如此優(yōu)美,每個節(jié)點只被訪問一次,使得時間效率應(yīng)該也是最優(yōu)的,并且還能求出答案,真是Unbelievable!
這題還能這么解!!!這題讓求最大路徑和,實際上是求根節(jié)點向下最大延申,而路徑和只是順帶著求出來的。
為什么不直接給出答案?這是一道hard的題目,如果不寫前面的鋪墊直接給出答案,多半是看不懂的。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/74297.html
摘要:示例輸入輸出示例輸入輸出說明和的長度小于。和均不以零開頭,除非是數(shù)字本身。舉例說明這兩個數(shù)的乘積的長度一定不會超過,分別是字符串的長度。第一輪第二輪至此該數(shù)組變?yōu)槿缓笤購奈膊刻幚磉M位。 題目地址:https://leetcode-cn.com/probl...題目描述:給定兩個以字符串形式表示的非負整數(shù) num1 和 num2,返回 num1 和 num2 的乘積,它們的乘積也表示為字...
摘要:圖因此可以成為樹,在所有可能的樹中,具有最小高度的樹被稱為最小高度樹。給出這樣的一個圖,寫出一個函數(shù)找到所有的最小高度樹并返回他們的根節(jié)點。因此使用一個數(shù)組代表每個節(jié)點的入度,若入度為就是葉子節(jié)點。 題目地址:https://leetcode-cn.com/probl...題目描述: 對于一個具有樹特征的無向圖,我們可選擇任何一個節(jié)點作為根。圖因此可以成為樹,在所有可能的樹中,具有最小...
摘要:關(guān)于遞歸這里提一兩點遞歸基本有這幾步遞歸的模板,終止條件,遞歸調(diào)用,邏輯處理。 ?作者簡介:大家好,我是車神哥,府學(xué)路18號的車神? ?個人主頁:應(yīng)無所住而生...
摘要:對于每個氣球,提供的輸入是水平方向上,氣球直徑的開始和結(jié)束坐標(biāo)。可以射出的弓箭的數(shù)量沒有限制。弓箭一旦被射出之后,可以無限地前進。我們想找到使得所有氣球全部被引爆,所需的弓箭的最小數(shù)量。解答這是一道區(qū)間覆蓋問題,不太好說清楚,利用模板即可。 題目地址:https://leetcode-cn.com/probl...題目描述:在二維空間中有許多球形的氣球。對于每個氣球,提供的輸入是水平方...
閱讀 3702·2021-11-23 09:51
閱讀 1360·2021-11-10 14:35
閱讀 4008·2021-09-22 15:01
閱讀 1279·2021-08-19 11:12
閱讀 379·2019-08-30 15:53
閱讀 1690·2019-08-29 13:04
閱讀 3429·2019-08-29 12:52
閱讀 3055·2019-08-23 16:14