生活随笔
收集整理的這篇文章主要介紹了
LeetCode——树:BST
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
BST
目錄
概述修剪二叉查找樹(LeetCode669)尋找二叉查找樹的第k個元素(LeetCode230)把二叉查找樹每個節點的值都加上比它大的節點的值二叉查找樹的最近公共祖先(LeetCode235)二叉樹的最近公共祖先(LeetCode236)從有序數組中構建二叉查找樹(LeetCode108)根據有序鏈表構建平衡的二叉查找樹(LeetCode109)在二叉查找樹中尋找兩個節點,使它們的和為一個給定值(LeetCode653)在二叉查找樹中查找兩個節點之差的最小絕對值(LeetCode530)
0. 概述
1. 二叉查找樹(BST):根節點大于左子樹所有節點,小于等于右子樹所有節點2. 二叉查找樹中序遍歷有序
1. 修剪二叉查找樹(LeetCode669)
概述 給定一個二叉搜索樹,同時給定最小邊界L 和最大邊界 R。通過修剪二叉搜索樹,使得所有節點的值在[L, R]中 (R>=L) 。你可能需要改變樹的根節點,所以結果應當返回修剪好的二叉搜索樹的新的根節點。
思路 由二叉樹的性質可知,如果root.val大于R,說明root的右邊節點全都大于R,所有可以直接跳到它的root.left繼續遍歷。同理如果root.val小于L,說明它的左邊節點全部小于L,所有直接跳到它的右節點繼續遍歷如果符合,則遞歸到下一個節點,構建新的二叉樹節點
root.left = trim(root.left, L, R)
root.right = trim(root.right, L, R) 代碼
public static TreeNode trimBST
(TreeNode root
, int L
, int R
) {
if (root
== null)return null;if (root
.val
> R
) {
return trimBST
(root
.left, L
, R
);}
if (root
.val
< L
) {
return trimBST
(root
.right, L
, R
);}root
.left = trimBST
(root
.left, L
, R
);root
.right = trimBST
(root
.right, L
, R
);return root
;}
2. 尋找二叉查找樹的第k個元素(LeetCode230)
概述 給定一個二叉搜索樹,編寫一個函數 kthSmallest 來查找其中第 k 個最小的元素。
思路 利用中序遍歷,遍歷的結果就是有序的,返回第k個結果即可 代碼
static
int cnt
= 0;static
int val
;public static
int kthSmallest
(TreeNode root
, int k
) {inOrder
(root
, k
);return val
;}private static void inOrder
(TreeNode root
, int k
) {
if (root
== null)return;inOrder
(root
.left, k
);cnt
++;if (k
== cnt
) {val
= root
.val
;return;}inOrder
(root
.right, k
);}
3. 把二叉查找樹每個節點的值都加上比它大的節點的值
概述
思路
1. 按照節點值降序遍歷所有節點,同時記錄已經遍歷過的節點值的和,并把這個和加到當前節點的值中。這種遍歷樹的方法被稱作反序中序遍歷。
2. 具體就是先遍歷右子樹,然后記錄遍歷過的值的和,加到當前節點的值中代碼
private static
int sum
= 0;public static TreeNode convertBST
(TreeNode root
) {traver
(root
);return root
;}private static void traver
(TreeNode node
) {
if (node
== null)return;traver
(node
.right);sum
+= node
.val
;node
.val
= sum
;traver
(node
.left);}
4. 二叉查找樹的最近公共祖先(LeetCode235)
概述 給定一個二叉搜索樹, 找到該樹中兩個指定節點的最近公共祖先。
思路 利用二叉查找樹性質,如果當前節點root.val>p.val&&root.val>q.val,那么要找的公共節點就在左子樹上如果root.val<p.val&&roo.val<q.val,那么要找的節點就在右子樹上否則找到公共節點返回即可 代碼
public static TreeNode lowestCommonAncestor
(TreeNode root
, TreeNode p
, TreeNode q
) {
if (root
.val
> p
.val
&& root
.val
> q
.val
)return lowestCommonAncestor
(root
.left, p
, q
);if (root
.val
< p
.val
&& root
.val
< q
.val
)return lowestCommonAncestor
(root
.right, p
, q
);return root
;}
5. 二叉樹的最近公共祖先(LeetCode236)
概述
給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。
思路
利用遞歸,從下往上判斷,如當前節點是5,則判斷它的左邊節點有沒有等于p,q的節點,判斷它的右邊節點有沒有等于p,q的節點
1. 如果left和right不為null,則說明找到公共節點,返回root
2. 如果left不為null,right為null,說明找到一邊的節點,返回left
3. 如果left為null,返回right 代碼
public static TreeNode lowestCommonAncestor
(TreeNode root
, TreeNode p
, TreeNode q
) {
if (root
== null || root
== p
|| root
== q
) {
return root
;}TreeNode
left = lowestCommonAncestor
(root
.left, p
, q
);TreeNode
right = lowestCommonAncestor
(root
.right, p
, q
);return left == null ?
right :
right == null ?
left : root
;}
6. 從有序數組中構建二叉查找樹(LeetCode108)
概述
將一個按照升序排列的有序數組,轉換為一棵高度平衡二叉搜索樹。
思路
從中間元素開始創建二叉查找樹
1. 獲取中間元素下標int mIdx=(sIdx+eIdx)/2
2. 創建根節點TreeNode root = new TreeNode(nums[mIdx])
3. 遞歸創建左右節點
root.left = toBST(nums, sIdx, mIdx-1)
root.right = toBST(nums, mIdx+1, eIdx)
4. 最后返回root即可 代碼
public static TreeNode sortedArrayToBST
(int[] nums
) {
return toBST
(nums
, 0, nums
.length
- 1);}private static TreeNode toBST
(int[] nums
, int sIdx
, int eIdx
) {
if (sIdx
> eIdx
)return null;int mid
= (sIdx
+ eIdx
) / 2;TreeNode root
= new TreeNode
(nums
[mid
]);root
.left = toBST
(nums
, sIdx
, mid
- 1);root
.right = toBST
(nums
, mid
+ 1, eIdx
);return root
;}
7. 根據有序鏈表構建平衡的二叉查找樹(LeetCode109)
概述
給定一個單鏈表,其中的元素按升序排序,將其轉換為高度平衡的二叉搜索樹。
思路
給定列表中的中間元素將會作為二叉搜索樹的根,該點左側的所有元素遞歸的去構建左子樹,同理右側的元素構建右子樹。這樣能保證最后構建出的二叉搜索樹是平衡的關鍵的找到中間元素
1. 利用快慢指針,慢指針每次走一步,快指針每次走兩步,當fast指針為null,或者fast.next指針為null時,pre.next就是中間元素找到中間節點后,將中間節點mid的前一個節點preMid.next=null,斷開。然后創建新節點new TreeNode(mid.val)node的左節點為從head開始的鏈表繼續遞歸。node的右節點為mid.next元素開始的鏈表繼續遞歸 代碼
public static TreeNode sortedListToBST
(ListNode head
) {
if (head
== null)return null;if (head
.next == null)return new TreeNode
(head
.val
);ListNode preMid
= preMid
(head
);ListNode mid
= preMid
.next;preMid
.next = null;TreeNode t
= new TreeNode
(mid
.val
);t
.left = sortedListToBST
(head
);t
.right = sortedListToBST
(mid
.next);return t
;}private static ListNode preMid
(ListNode head
) {ListNode slow
= head
;ListNode fast
= head
.next;ListNode pre
= head
;while (fast
!= null && fast
.next != null) {pre
= slow
;slow
= slow
.next;fast
= fast
.next.next;}
return pre
;}
8. 在二叉查找樹中尋找兩個節點,使它們的和為一個給定值(LeetCode653)
概述 給定一個二叉搜索樹和一個目標結果,如果 BST 中存在兩個元素且它們的和等于給定的目標結果,則返回 true。
思路 利用HashSet,在遍歷過程中,將元素放入set中。對于每個值為p的節點,在set中檢查是否存在k-p。如果存在,那么在該樹上就能找到兩個節點的和為k;否則,將p放入set中如果遍歷完整棵樹都沒有找到一對節點和為k,那么該樹上不存在兩個和為k的節點 代碼
public boolean findTarget
(TreeNode root
, int k
){
Set<Integer> set = new HashSet
<>();return find
(root
,k
,set);}private
boolean find
(TreeNode root
, int k
, Set<Integer> set) {
if (root
==null)return false;if (set.contains(k
-root
.val
))return true;set.add(root
.val
);return find
(root
.left,k
,set)||find
(root
.right,k
,set);}
9. 在二叉查找樹中查找兩個節點之差的最小絕對值(LeetCode530)
概述 給你一棵所有節點為非負值的二叉搜索樹,請你計算樹中任意兩節點的差的絕對值的最小值。
思路
1. 要求任意兩節點絕對值最小,根據二叉搜索樹中序遍歷結果有序,則是計算前后兩個節點的差,從中選擇最小的差值即可代碼
private
int minDiff
= Integer.MAX_VALUE
;private TreeNode preNode
= null;public int getMinimumDifference
(TreeNode root
) {inOrder
(root
);return minDiff
;}private void inOrder
(TreeNode node
) {
if (node
== null)return;inOrder
(node
.left);if (preNode
!= null)minDiff
= Math
.min(minDiff
, node
.val
- preNode
.val
);preNode
= node
;inOrder
(node
.right);}
總結
以上是生活随笔為你收集整理的LeetCode——树:BST的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。