938 二叉搜尋樹的範圍和 前序遍歷雙剪支的應用

2021-10-03 04:20:40 字數 3199 閱讀 4398

給定二叉搜尋樹的根結點 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,null,6]

, l =

6, r >=

10輸出:23

樹中的結點數量最多為 10000 個。

最終的答案保證小於 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...