1. 程式人生 > >LeetCode098——驗證二叉搜尋樹

LeetCode098——驗證二叉搜尋樹

題目描述:

知識點:二叉搜尋樹、遞迴

思路一:遞迴判斷

遞迴終止條件

如果root節點為null或者root的左右節點均為null,我們直接返回true。

遞迴過程

(1)如果root的左節點為null且右節點不為null。

如果此時root的值小於右子樹中的最小值且root的右子樹是一棵二分搜尋樹,返回true。否則,返回false。

(2)如果root的左節點不為null且右節點為null。

如果此時root的值大於左子樹中的最大值且root的左子樹是一棵二分搜尋樹,返回true。否則,返回false。

(3)如果root的左右節點均不為null。

如果此時root的值大於左子樹中的最大值且小於右子樹中的最小值且root的左右子樹均是一棵二分搜尋樹,返回true。否則,返回false。

時間複雜度是O(n),其中n為樹中的節點個數。空間複雜度即遞迴深度,是O(h),其中h為樹的高度。

JAVA程式碼:

public class Solution {

    public boolean isValidBST(TreeNode root) {
        if(root == null ||(root.left == null && root.right == null)){
            return true;
        }
        if(root.left == null && root.right != null){
            if(root.val < findMinTreeNode(root.right) && isValidBST(root.right)){
                return true;
            }
        }else if(root.left != null && root.right == null){
            if(root.val > findMaxTreeNode(root.left) && isValidBST(root.left)){
                return true;
            }
        }else if(root.left != null && root.right != null){
            if(root.val < findMinTreeNode(root.right) && root.val > findMaxTreeNode(root.left) && isValidBST(root.left) && isValidBST(root.right)){
                return true;
            }
        }
        return false;
    }

    private int findMinTreeNode(TreeNode root){
        while(root.left != null){
            root = root.left;
        }
        return root.val;
    }

    private int findMaxTreeNode(TreeNode root){
        while(root.right != null){
            root = root.right;
        }
        return root.val;
    }
}

LeetCode解題報告:

思路二:中序遍歷

對於一棵二分搜尋樹而言,其中序遍歷的結果是一個遞增序列。這裡我採用的是遞迴的形式實現中序遍歷,更多中序遍歷演算法請見LeetCode094——二叉樹的中序遍歷

時間複雜度是O(n),其中n為樹中的節點個數。空間複雜度也是O(n)。

JAVA程式碼:

public class Solution {

    List<Integer> list;

    public boolean isValidBST(TreeNode root) {
        list = new ArrayList<>();
        inorderTraversal(root);
        for(int i = 1; i < list.size(); i++){
            if(list.get(i) <= list.get(i - 1)){
                return false;
            }
        }
        return true;
    }

    private void inorderTraversal(TreeNode root){
        if(root == null){
            return;
        }
        inorderTraversal(root.left);
        list.add(root.val);
        inorderTraversal(root.right);
    }
}

LeetCode解題報告:

思路三:思路二的改進

思路二把中序遍歷的結果都儲存在了一個List集合裡,在遍歷完成之後判斷集合中的元素是否按遞增順序排列。事實上,我們完全可以在中序遍歷的過程中就對結果進行驗證。這裡我採用的是遞迴的形式實現中序遍歷,更多中序遍歷演算法請見LeetCode094——二叉樹的中序遍歷​​​​​​​。

時間複雜度是O(n),其中n為樹中的節點個數。空間複雜度即遞迴深度,是O(h),其中h為樹的高度。

JAVA程式碼:

public class Solution {

    Integer pre = null;

    public boolean isValidBST(TreeNode root) {
        return inorderTraversal(root);
    }

    private boolean inorderTraversal(TreeNode root){
        if(root == null){
            return true;
        }
        if(!inorderTraversal(root.left)){
            return false;
        }
        if(pre != null && root.val <= pre){
            return false;
        }
        pre = root.val;
        if(!inorderTraversal(root.right)){
            return false;
        }
        return true;
    }
}

LeetCode解題報告: