1. 程式人生 > 實用技巧 >【40講系列5】二叉樹、二叉搜尋樹

【40講系列5】二叉樹、二叉搜尋樹

一、理論

二、典型例題

☆☆①:驗證二叉搜尋樹(LC98)

思路:中序遍歷時,判斷當前節點是否大於中序遍歷的前一個節點,如果大於,滿足BST,繼續遍歷;否則返回false。

中序遍歷(遞迴):

class Solution {
    private TreeNode pre; // 前一個節點, 定義為全域性的

    public boolean isValidBST(TreeNode root) {
        if (root == null) return true;
        // 訪問左子樹
        if(!isValidBST(root.left)){
            
return false; } // 訪問當前節點,如果當前節點<=中序遍歷的前一個節點,直接返回false if (pre != null && pre.val >= root.val){ return false; } pre = root; // 訪問右子樹 return isValidBST(root.right); } }

中序遍歷(非遞迴):

class Solution {
    public boolean isValidBST(TreeNode root) {
        
if (root == null) return true; Stack<TreeNode> stack = new Stack<TreeNode>(); TreeNode pre = null; while (root != null || !stack.isEmpty()){ while (root != null){ stack.push(root); root = root.left; } root
= stack.pop(); if (pre != null && pre.val >= root.val){ return false; } pre = root; root = root.right; } return true; } }

☆☆②:二叉樹的最近公共祖先(LC236)

class Solution {
    // 時間複雜度O(n)
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null)
            return null;
        if (p == root || q == root)  // 其中一個節點就在根節點的位置
            return root;
        TreeNode left = lowestCommonAncestor(root.left,p,q);
        TreeNode right = lowestCommonAncestor(root.right,p,q);
        if (left != null && right != null) return root;
        if (left == null) return right;
        if (right == null) return left;
        return null; // left和right都為空(即左右子樹都不包含pq)
    }
}

③:二叉搜尋樹的最新公共祖先(LC235)

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        // 遞迴寫法
        /*
        if (p.val < root.val && q.val < root.val){
            return lowestCommonAncestor(root.left,p,q);
        }
        if (p.val > root.val && q.val >root.val){
            return lowestCommonAncestor(root.right,p,q);
        }
        return root; // 對應三種情況
        */
        // 非遞迴寫法
        while (root != null){
            if (p.val < root.val && q.val < root.val){
                root = root.left;
            }else if (p.val > root.val && q.val > root.val){
                root = root.right;
            }else{
                return root;
            }
        }
        return null;
    }
}