驗證二叉搜索樹(leetcode 98)

題目

給定一個二叉樹,判斷其是否是一個有效的二叉搜索樹。

假設一個二叉搜索樹具有如下特徵:

節點的左子樹只包含小於當前節點的數。
節點的右子樹只包含大於當前節點的數。
所有左子樹和右子樹自身必須也是二叉搜索樹。
示例 1:
2/ 1   3
示例 2:
在這裏插入圖片描述

解析

做這個題的時候,我的第一想法就是說驗證左節點小於根,右節點大於根不就行了。但是這種想法是錯的,比如下圖的這種情況:
在這裏插入圖片描述
很明顯,這不是一顆二叉搜索樹,因爲4小於5,所以上述方法是行不通的,那麼我們應該怎麼辦?這裏提供兩種解法

解法一

利用二叉搜索樹中序遍歷的性質,中序遍歷的結果一定是升序的,如果不滿足,就說明不是二叉搜索樹。這個方法時間複雜度O(N),下面貼出代碼:
code

public boolean isValidBST(TreeNode root) {
        //存儲遍歷的結果
        List<Integer> list = new ArrayList<>();
        //調用中序遍歷
        midOrder(root,list);
        //驗證是否升序
        for (int i = 0; i < list.size()-1 ; i++) {
            if (list.get(i)>=list.get(i+1)){
                return false;
            }
        }
        return true;
    }
    //中序遍歷,當然還可以採用非遞歸的棧的方式
    public void midOrder(TreeNode root,List<Integer> list){
        if (root == null){
            return;
        }
        midOrder(root.left,list);
        list.add(root.val);
        midOrder(root.right,list);
    }
解法二

第二種方法時間複雜度也是O(N),但是代碼比較有美感,可能不太好理解,大家可以看代碼。
這裏需要獲取root左子樹的最大節點maxleft和右子樹的最小節點minright,然後要求maxleft.val < root && root.val < minright。
code

//使用遞歸
    public boolean isValidBST(TreeNode root) {
        return isValidBST(root,Long.MIN_VALUE,Long.MAX_VALUE);
    }

    //比較反人類的是思想,如果想不通就去debug一下
    private boolean isValidBST(TreeNode root, long minValue, long maxValue) {
        if (root == null){
            return true;
        }
        if (root.val<=minValue){
            return false;
        }
        if (root.val>=maxValue){
            return false;
        }
        return isValidBST(root.left,minValue,root.val)&&isValidBST(root.right,root.val,maxValue);
    }

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/validate-binary-search-tree

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章