LeetCode 98. 驗證二叉搜索樹

98. 驗證二叉搜索樹

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

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

  • 節點的左子樹只包含小於當前節點的數。
  • 節點的右子樹只包含大於當前節點的數。
  • 所有左子樹和右子樹自身必須也是二叉搜索樹。
示例1:
輸入:
    2
   / \
  1   3
輸出: true
示例2:
輸入:
    5
   / \
  1   4
     / \
    3   6
輸出: false
解釋: 輸入爲: [5,1,4,null,null,3,6]。
     根節點的值爲 5 ,但是其右子節點值爲 4 。

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/validate-binary-search-tree/
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

  • 1. 遞歸法

思路:

  1. 遞歸終止條件爲當前節點爲空
  2. 判斷當前節點是否滿足二叉樹性質(左子樹都小於根節點 & 右子樹都大於根節點)
  3. 遞歸判斷左右子樹是否滿足條件
  • 注意:要判斷右子樹中所有節點都要大於根節點纔可以
    public boolean isValidBST(TreeNode root) {
        return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }

    private boolean isValidBST(TreeNode root, long minVal, long maxVal) {
        if (root == null) return true;
        if (root.val >= maxVal || root.val <= minVal) return false;
        return isValidBST(root.left, minVal, root.val) && isValidBST(root.right, root.val, maxVal);
    }

複雜度分析:

  • 時間複雜度:O(n), 需要遍歷所有節點進行判斷

  • 空間複雜度:O(n), 遞歸深度可能達到n層

  • 2. 迭代法

需要使用(中序遍歷)LeetCode 94. 二叉樹的中序遍歷 - 簡書

思路: 二叉搜索樹中序遍歷後的結果一定是從小到達排列的

public boolean isValidBST(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        long res = Long.MIN_VALUE;
        while (cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            if (cur.val < res) return false;
            else res = cur.val;
            cur = cur.right;
        }
        return true;
    }

複雜度分析:

  • 時間複雜度:O(n), 最壞情況下我們需要遍歷每個元素添加到stack中

  • 空間複雜度:O(n), 棧中需要存儲 n 個元素

  • 3. 中序遍歷

思路:

  1. 創建 list,遞歸進行中序遍歷,將每個節點的值添加到 list中
  2. 遍歷 list, 判斷是否是從小到大進行排序的,如果是則一定是二叉搜索樹,否則一定不是
public boolean isValidBST(TreeNode root) {
        List<Long> list = new ArrayList<>();
        helper(root, list);
        for (int i = 1; i < list.size(); i++) {
            if (list.get(i) - list.get(i - 1) <= 0) return false;
        }
        return true;
    }

    private void helper(TreeNode root, List<Long> list) {
        if (root == null) return;
        helper(root.left, list);
        list.add((long) root.val);
        helper(root.right, list);
    }

複雜度分析:

  • 時間複雜度:O(n + n), 需要遍歷每個節點進行遞歸比較,最後還需要遍歷 list 查看順序
  • 空間複雜度:O(n + n), 中序遍歷過程中使用了遞歸,並且還需要創建大小爲 n 的 list

  • 源碼

  • 我會每天更新新的算法,並儘可能嘗試不同解法,如果發現問題請指正
  • Github
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章