常见面试算法题(树专题二:BST)

141 阅读2分钟

第三部分、二叉搜索树相关

二叉搜索树最大的性质:中序遍历是递增的

1. 验证二叉搜索树

leetcode-cn.com/problems/va…


class Solution {
    public boolean isValidBST(TreeNode root) {
        if(root == null) return true;
        return dfs(root , Long.MIN_VALUE , Long.MAX_VALUE);
    }

    boolean dfs(TreeNode root , long min , long max){
        if(root == null) return true;
        //如果root的值比最小值还小或者比最大值还大,说明不是BST
        if(root.val <= min || root.val >= max) return false;
        return dfs(root.left , min , root.val) && dfs(root.right , root.val , max);
    }
}

2. 二叉搜索树的第k大节点

leetcode-cn.com/problems/er…

class Solution {
    TreeNode cur = null;
    int count = 0;
    int res = 0;
    public int kthLargest(TreeNode root, int k) {
        if(root == null) return 0;
        dfs(root , k);
        return res;
    }

    void dfs(TreeNode root , int k){
        if(root == null) return;
        dfs(root.right , k); //注意中序遍历反过来
        cur = root;
        count++; //记录是否到第k个了,如果到了就计入res返回
        if(count == k){
            res = root.val;
            return;
        }
        dfs(root.left , k);
    }
}

3. 二叉搜索树的最小绝对差

leetcode-cn.com/problems/mi…

class Solution {
    TreeNode pre = null;
    int res = Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
        if(root == null) return 0;
        dfs(root);
        return res;
    }

    void dfs(TreeNode root){
        if(root == null) return;
        dfs(root.left);
        if(pre != null) res = Math.min(res , root.val - pre.val);
        pre = root;
        dfs(root.right);
    }
}

4. 删除二叉搜索树中的节点

leetcode-cn.com/problems/de…

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if(root == null) return null;
        if(root.val < key) root.right =  deleteNode(root.right , key);
        else if(root.val > key) root.left =  deleteNode(root.left , key);
        else{
            //找到节点了
            //1.左右子树有一个为空,返回另外一个子树作为根节点
            if (root.left == null) return  root.right;
            else if (root.right == null) return root.left;
            else{
                // 左右子树都存在,返回后继节点(右子树最左叶子)作为新的根
                // 把原来的左子树 接到中继节点的左子树上
                TreeNode cur = root.right;
                while (cur.left != null) cur = cur.left;
                cur.left = root.left;
                return root.right;
            }
        }
        return root;
    }
}

5. 插入二叉搜索树中的节点

leetcode-cn.com/problems/in…

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null) return new TreeNode(val);

        TreeNode p = root , cur = root;
        while(cur != null){ // cur往下找,p记住原来的位置
            p = cur;
            cur = cur.val > val ? cur.left : cur.right;
        }

        if(p.val < val) p.right = new TreeNode(val);
        else p.left = new TreeNode(val);
        return root;
    }
}

6. 搜索二叉搜索树中的节点

leetcode-cn.com/problems/se…

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null) return null;
        if(root.val > val) return searchBST(root.left , val);
        else if(root.val < val) return searchBST(root.right, val);
        else return root;
    }
}

7. 验证是否是二叉搜索树的后序遍历

leetcode-cn.com/problems/er…

class Solution {
    //左右中
    public boolean verifyPostorder(int[] postorder) {
        return dfs(postorder , 0 , postorder.length-1);
    }

    boolean dfs(int[] postorder , int l , int r){
        if(l >= r) return true;
        int index = l;
        while(postorder[index] < postorder[r]) index++;
        int mid = index;
        while(postorder[index] > postorder[r]) index++;
        if(index != r ) return false;
        return dfs(postorder , l , mid-1) && dfs(postorder , mid , r-1);
    }
}

8. 有序数组转换成二叉搜索树

leetcode-cn.com/problems/co…

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        if(nums == null || nums.length == 0) return null;
        return dfs(nums , 0 , nums.length-1);
    }

    TreeNode dfs(int[] nums, int l , int r){
        if(l > r) return null;
        int mid = l + r >> 1;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = dfs(nums , l , mid-1);
        root.right = dfs(nums , mid + 1, r);
        return root;
    }
}

9. 有序链表转换成二叉搜索树

leetcode-cn.com/problems/co…

class Solution {
    public TreeNode sortedListToBST(ListNode head) {
        if(head == null) return null;
        return dfs(head , null);
    }

    TreeNode dfs(ListNode head , ListNode tail){
        if(head == tail) return null;
        ListNode fast = head;
        ListNode slow = head;
        while(fast.next != tail && fast.next.next != tail){
            fast = fast.next.next;
            slow = slow.next;
        }
        TreeNode root = new TreeNode(slow.val);
        root.left = dfs(head,slow);
        root.right = dfs(slow.next , tail);
        return root;
    }
}

10. 二叉搜索树的最近公共祖先

leetcode-cn.com/problems/lo…

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null) return root;
        if(root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right,p,q);
        else if(root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left , p , q);
        else return root;
        
    }
}