給定二叉搜尋樹的根結點 root,返回 l 和 r(含)之間的所有結點的值的和。然後我們知道每個節點都有乙個值,題目要求把節點值位於閉區間內的節點值加起來求和。二叉搜尋樹保證具有唯一的值。
示例 1:
輸入:root =[10
,5,15
,3,7
,null,18]
, l =
7, r =
15輸出:32
示例 2
樹中的結點數量最多為 10000 個。輸入:root =[10
,5,15
,3,7
,13,18
,1,null,6]
, l =
6, r >=
10輸出:23
最終的答案保證小於 2^31。
也就是說返回值是乙個證書和。題目中也提示了大小為2的32次方,剛好就是4個位元組大小的integer型別。所以我們可以宣告乙個全域性變數在存放這個和。
那麼思路大概可以確定為,從根節點開始遍歷二叉樹,把滿足條件的節點值累計到全域性變數sum。
那麼我們還有乙個疑問,需要每個節點都訪問一次嘛?我們在思考「需要不需要」之前,先確定「是否可行「。如果可行的話再考慮需不需要(如果方案不可行,那也就沒有必要了)。用暴力演算法每個節點訪問一次,按照我們前面的思路是可行的。
那接下來我們需要思考有沒有必要每個節點都訪問?我們先從條件下手,首先我們判斷是否滿足條件的依據是判斷節點值的大小。也就是說節點值相對我們的條件會有3種結果:小於區間範圍,屬於區間範圍,大於區間範圍。
首先我們能馬上確定的就是【屬於區間】訪問的節點直接累加到全域性變數sum。什麼叫屬於,就是小於等於左邊界l,大於等於右邊界r。
至於小於或大於區間範圍的節點是否可以影響到我們的遍歷行為呢?如果不影響我們就忽略這樣的節點,繼續按流程分別遍歷左右子樹,直到訪問完所有節點。真正的答案肯定是【有影響】。
理由就是我們的二叉樹,不是普通的二叉樹,如果是普通二叉樹,節點值之間沒有任何結構分布規律。我們從上面二叉樹的定義性質就可以得出,不存在一條於節點值大小有關的性質。
而二叉搜尋樹bst,有一條與節點值大小有關的性質:所有節點按照大小約定,任何節點值大於左子節點值,且小於右節點值。
利用二叉搜尋樹的節點大小性質可以得出。
如果當前節點值【小於等於】區間最小值(閉區間左邊界的值)那麼就沒必要訪問左節點了(而不是忽略比較結果繼續暴力遍歷)。
如果當前節點值【大於等於】區間最大值(閉區間的右邊界的值)那麼就沒必要訪問右節點。
另外還有乙個細節,就是為什麼強調【等於】也沒必要繼續訪問左節點或者有節點呢?因為題目中還有乙個條件,【二叉搜尋樹保證具有唯一的值。】表示每個節點值都是唯一的。
到這裡我們似乎把所有條件的用上了。
然後我要還需要確定另乙個事情,就是採用什麼遍歷方案呢?前序遍歷?中序遍歷?後續遍歷?,我們是根據當前節點的值來決定是否進行後續的子樹遍歷,所以當然是採用的方案是【前序遍歷】。
可以開始程式設計了。
備註:利用二叉樹搜尋樹的性質減少節點的遍歷動作,叫「剪支技術「。意思就是剪掉樹的分支,減少不要的遍歷操作。
**框架如下:
class
solution
// 訪問節點,讀取或者修改屬性值。
// 遞迴訪問左右子樹
recursive
(node.left)
;recursive
(node.right)
;// 也可以在這裡讀取或者修改屬性值,這種是回溯思路。
// 返回值。
return node;
}}
(這裡不要扯複雜先。專心學習框架。暴力解題。)
開始解題:
/**
* definition for a binary tree node.
* public class treenode
* }*/class
solution
/** explain: 小於等於左邊界的話不訪問左子樹 */
private
boolean
isnotvisitleft
(int nodeval)
/** explain: 大於等於左邊界的話不訪問右子樹 */
private
boolean
isnotvisitright
(int nodeval)
treenode recursive
(treenode node)
// 訪問節點,讀取或者修改屬性值。 if(
isbelongtoscope
(node.val)
)// 遞迴訪問左右子樹if(
isnotvisitleft
(node.val)
)elseif(
isnotvisitright
(node.val)
)else
// 也可以在這裡讀取或者修改屬性值,這種是回溯思路。
// 返回值。
return node;
}public
intrangesumbst
(treenode root,
int l,
int r)
solution.l = l;
solution.r = r;
// leefcode的全域性遍歷,一定要在入口函式初始化,不大聰明的亞子
solution.sum =0;
// explain: 前序遍歷把滿足條件的節點值累計
recursive
(root)
;// explain: 返回累加的最終結果
return solution.sum;
}}
比如這樣寫:
treenode recursive
(treenode node)
// 前序遍歷。 if(
isbelongtoscope
(node.val)
)recursive
(node.left)
;recursive
(node.right)
;return node;
}
938 二叉搜尋樹的範圍和
題意 給定二叉搜尋樹的根結點 root,返回 l 和 r 含 之間的所有結點的值的和。二叉搜尋樹保證具有唯一的值。思路 題意不難,但是對python的因為是的動態語言,所以不會優先使用全域性變數,所以要指定變數 code class solution object defrangesumbst se...
938 二叉搜尋樹的範圍和
輸入 root 10,5,15,3,7,null,18 l 7,r 15 輸出 32 10 7 15 輸入 root 10,5,15,3,7,13,18,1,null,6 l 6,r 10 輸出 23 10 7 6 剪枝 不剪枝class solution int ans 0 ans ans ran...
938 二叉搜尋樹的範圍和
938.二叉搜尋樹的範圍和 給定二叉搜尋樹的根結點 root,返回 l 和 r 含 之間的所有結點的值的和。二叉搜尋樹保證具有唯一的值。示例 1 輸入 root 10,5,15,3,7,null,18 l 7,r 15 輸出 32 示例 2 輸入 root 10,5,15,3,7,13,18,1,n...