給你一棵以 root 為根的 二叉樹 ,請你返回 任意 二叉搜尋子樹的最大鍵值和。
二叉搜尋樹的定義如下:
任意節點的左子樹中的鍵值都 小於 此節點的鍵值。
任意節點的右子樹中的鍵值都 大於 此節點的鍵值。
任意節點的左子樹和右子樹都是二叉搜尋樹。
示例 1:
輸入:root = [1,4,3,2,4,2,5,null,null,null,null,null,null,4,6]
輸出:20
解釋:鍵值為 3 的子樹是和最大的二叉搜尋樹。
示例 2:
輸入:root = [4,3,null,1,2]
輸出:2
解釋:鍵值為 2 的單節點子樹是和最大的二叉搜尋樹。
示例 3:
輸入:root = [-4,-2,-5]
輸出:0
解釋:所有節點鍵值都為負數,和最大的二叉搜尋樹為空。
示例 4:
輸入:root = [2,1,3]
輸出:6
示例 5:
輸入:root = [5,4,8,3,null,6,3]
輸出:7
每棵樹最多有 40000 個節點。
每個節點的鍵值在 [-4 * 10^4 , 4 * 10^4] 之間。
這道題比較麻煩的一點是要判斷這棵樹是不是二叉搜尋樹。這裡我借(chao)鑑(xi)了大佬的做法。這裡我們用到了樹形dp的做法:先向子樹進行遞迴,遞迴的過程中判斷自己的左右兒子符不符合二叉搜尋樹的條件。返回的時候,需要返回四個狀態:自己符不符合二叉搜尋樹?目前我這個子樹上的最大鍵值是多少?最小鍵值是多少(用於給自己的根節點判斷符不符合二叉搜尋樹)?現在的鍵值和是多少?這裡大佬有個技巧:如果需要返回多個值,可以選擇返回乙個vector記錄這些狀態。另外,需要要注意遇到null節點時的處理。
int ans=0;
class
solution
; vector<
int> ar=
dfs(root-
>right)
; vector<
int> al=
dfs(root-
>left);if
(!ar[0]
||!al[0]
||root-
>val<=al[2]
||root-
>val>=ar[1]
);}int sum=ar[3]
+al[3]
+root-
>val;
int maxnn=root-
>right==
null
?root-
>val:ar[2]
;int minn=root-
>left==
null
?root-
>val:al[1]
; ans=
max(ans,sum)
;return;}
intmaxsumbst
(treenode* root)
};
另外還有一種更好的寫法:
dfs的過程中,判斷這個子樹是否為二叉搜尋樹,是的話直接求這顆樹的鍵值和,比上面的方法快。
int ans=0;
class
solution
elseif(
!root-
>left)
else
//if(root->val==5) cout/cout
}int
calculate
(treenode*root)
void
dfs(treenode*root)
else
}int
maxsumbst
(treenode* root)
};
最大二叉搜尋子樹
有一棵二叉樹,其中所有節點的值都不一樣,找到含有節點最多 的搜尋二叉子樹,並返回這棵子樹的頭節點.給定二叉樹的頭結點root,請返回所求的頭結點,若出現多個節點最多的子樹,返回頭結點權值最大的。struct treenode class maxsubtree if root null return ...
最大二叉搜尋子樹
有一棵二叉樹,其中所有節點的值都不一樣,找到含有節點最多 的搜尋二叉子樹,並返回這棵子樹的頭節點.1 2 struct treenode 9 10 class maxsubtree 1718 treenode max node subtree treenode root,int maxval,int...
二叉樹中最大搜尋子樹和最大搜尋子結構
輸入描述 第一行輸入兩個整數 n 和 root,n 表示二叉樹的總節點個數,root 表示二叉樹的根節點。以下 n 行每行三個整數 fa,lch,rch,表示 fa 的左兒子為 lch,右兒子為 rch。如果 lch 為 0 則表示 fa 沒有左兒子,rch同理 ps 節點的編號就是節點的值。輸入 ...