今天在力扣上刷到兩道法相似的題目,都是使用區間分治然後遞迴構造樹的解決方法,感覺新有所得,於是決定記錄下來。
leetcode:將有序陣列轉換為二叉搜尋樹
將乙個按照公升序排列的有序陣列,轉換為一棵高度平衡二叉搜尋樹。
本題中,乙個高度平衡二叉樹是指乙個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過 1。
給定有序陣列: [-10,-3,0,5,9],
乙個可能的答案是:[0,-3,9,-10,null,5],它可以表示下面這個高度平衡二叉搜尋樹:
0/ \
-3 9
/ /
-10 5
看到平衡二叉搜尋樹——任意根結點的值大於等於左子樹的所有結點的值,而小於右子樹所有結點的值,並且任意結點的左右子樹高度差不超過1。撓撓頭,什麼左旋右旋的,不會寫呀,嚇得我有趕緊拿出資料結構老師ppt來複習下的衝動。
另外,這裡我還學習到區間分治採用左閉右閉的區間端點選取策略,以及(left + right)/ 2
的中間計算方法容易出現數值溢位情況,即left + right
的值超過int
最大值,所以中間值計算方法推薦使用left + (right - left) / 2
。
class
solution
return
build
(nums,
0, nums.length-1)
;// 區間分治:左閉右閉
}private treenode build
(int
nums,
int l,
int r)
int m = l +
(r - l)/2
;// (l + r)的值可能會大於int的最大值,即溢位
treenode root =
newtreenode
(nums[m]);
root.left =
build
(nums, l, m-1)
; root.right =
build
(nums, m+
1, r)
;return root;
}}
leetcode:從前序與中序遍歷序列構造二叉樹
根據一棵樹的前序遍歷與中序遍歷構造二叉樹。
例如,給出
前序遍歷 preorder = [3,9,20,15,7]
中序遍歷 inorder = [9,3,15,20,7]
返回如下的二叉樹:
3/ \
9 20
/ \
15 7
這題之前在牛客上做過一次,但是現在做的時候又是一臉懵。唯一確定步驟是,先從前序遍歷中拿到根結點,然後根據中序遍歷得到左右子樹。但是具體怎麼實現呢!!!
心想,這無非又是遞迴實現,在遞迴過程中,將大問題不斷的簡化成小問題,就像求斐波那契數列一樣。看到引數是兩個陣列,又聯想到上一題的區間分治策略,於是思路立刻來了。模仿一下上一題的**,一次就ac了。真開心,或許這就是學習和成長吧。
class
solution
return
build
(preorder,
0, preorder.length-
1, inorder,
0, inorder.length);}
private treenode build
(int
pre,
int l1,
int r1,
int[
] in,
int l2,
int r2)
int rootindex =0;
treenode root =
newtreenode
(pre[l1]);
for(
int i=l2; i<=r2; i++)}
root.left =
build
(pre, l1+
1, l1+rootindex-l2, in, l2, rootindex-1)
; root.right =
build
(pre, l1+rootindex-l2+
1, r1, in, rootindex+
1, r2)
;return root;
}}
LeetCode題解 56 合併區間
給出乙個區間的集合,請合併所有重疊的區間。示例 1 輸入 1,3 2,6 8,10 15,18 輸出 1,6 8,10 15,18 解釋 區間 1,3 和 2,6 重疊,將它們合併為 1,6 示例 2 輸入 1,4 4,5 輸出 1,5 解釋 區間 1,4 和 4,5 可被視為重疊區間。當區間按序排...
LeetCode 56 合併區間 題解
題目大意 給定一組區間,然後將有重疊部分的區間合併,注意如果兩個區間僅有乙個數重疊也算,比如 1,4 與 4,5 分析 直接按照區間的左端點大小公升序排序,如果相同則比較右端點,均按公升序。排序後,如果後乙個區間的左端點小於等於前乙個區間的右端點,那麼我們就認為這兩個區間可以合併,否則將前乙個區間認...
整數區間 題解
題目描述 乙個整數區間 a,b 請程式設計完成以下任務 1.從檔案中讀取區間的個數及其它們的描述 2.找到滿足下述條件的所含元素個數最少的集合中元素的個數,對於每乙個區間,都至少有兩個不同的整數屬於該集合。輸入 首行包括區間的數目 n,1 n 10000,接下來的 n 行,每行包括兩個整數 a,b,...