此題首先可以確定選用的演算法是遞迴
對於二叉搜尋樹我們可以知道其左葉子節點值《根節點值《右葉子節點值,故二叉搜尋樹的中序遍歷為乙個公升序陣列。即題目給的有序陣列。
中序遍歷:先遍歷左子樹,在遍歷根節點,最後遍歷右子樹。
如果不要求為平衡二叉搜尋樹的話,僅由乙個公升序陣列,樹的根節點就有多種不同的取值,就會產生很多個不同的二叉搜尋樹。
如當公升序陣列為:[-10,-3,0,5,9]時,幾種可能的情況為(還有其他情況,可以自己看一下,比較特殊):
如果要求為平衡二叉搜尋樹的話,即左右子樹的最大高度差要小於等於1,所以選中的根節點左右子樹的節點數量差要小於等於1,即選中公升序陣列的乙個值其左邊元素數的右邊元素數的差要小於等於1。
這樣就可以先求出公升序陣列的中間值即根節點然後左邊的就為左子樹,右邊的為右子樹,然後對左右子樹再次執行相同的操作,一直遞迴知道最後更節點的左右子樹均為空即可。
由於陣列長度可能為偶數也可能為奇數,所以選擇的中間值可能有差別,故最後產生的樹就會不一樣,這裡我們採用當陣列長度為奇數時,中間值即為所求,陣列長度為偶數時,有兩個中間值我們選取左邊的為根節點(當然也可以選擇右邊的)。
則求得中間值的公式為:
mid = (left+right)/2
mid = (left+right)>>1
mid = left+(rgiht-left)/2
以上三個公式均可,建議使用方式2,方式1當陣列長度較大時肯能產生溢位帶來不必要的麻煩,不過一般不會發生。
class
treenode
@override
public string tostring()
';}}
public
class
test108
; test108 test108 =
newtest108()
; test108.
sortedarraytobst
(nums);}
//中序遍歷,總是選擇中間位置左邊的數字作為根節點
//選擇中間位置左邊的數字作為根節點,則根節點的下標為 mid=(left+right)/2,此處的除法為整數除法。
//但是這樣計算有溢位風險,使用mid = left+(right-left)/2或者移位運算較合適
public treenode sortedarraytobst
(int
nums)
public treenode helper
(int
nums,
int left,
int right)
// 總是選擇中間位置左邊的數字作為根節點
int mid =
(left + right)/2
; system.out.
println
(left+
"--"
+right+
"--"
+mid)
; treenode root =
newtreenode
(nums[mid]);
root.left =
helper
(nums, left, mid -1)
; root.right =
helper
(nums, mid +
1, right)
; system.out.
println
(root)
;return root;
}
結果為:
treenode},
right=treenode
}}
圖示:
選擇其它位置為根節點類似,可自行推導。
LeetCode108 將有序陣列轉換為二叉搜尋樹
將乙個按照公升序排列的有序陣列,轉換為一棵高度平衡二叉搜尋樹。本題中,乙個高度平衡二叉樹是指乙個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過 1。示例 給定有序陣列 10,3,0,5,9 乙個可能的答案是 0,3,9,10,null,5 它可以表示下面這個高度平衡二叉搜尋樹 0 3 9 10...
LeetCode108 將有序陣列轉換為二叉搜尋樹
將乙個按照公升序排列的有序陣列,轉換為一棵高度平衡二叉搜尋樹。本題中,乙個高度平衡二叉樹是指乙個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過 1。示例 給定有序陣列 10,3,0,5,9 乙個可能的答案是 0,3,9,10,null,5 它可以表示下面這個高度平衡二叉搜尋樹 0 3 9 10...
leetcode108 將有序陣列轉換為二叉搜尋樹
將有序陣列轉換為二叉搜尋樹。難度 簡單。將乙個按照公升序排列的有序陣列,轉換為一棵高度平衡二叉搜尋樹。本題中,乙個高度平衡二叉樹是指乙個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過 1。示例 給定有序陣列 10,3,0,5,9 乙個可能的答案是 0,3,9,10,null,5 它可以表示下面...