日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode——树:BST

發布時間:2024/4/11 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。