98. 驗證二叉搜尋樹
知識點:二叉樹;遞迴
題目描述
給定一個二叉樹,判斷其是否是一個有效的二叉搜尋樹。
假設一個二叉搜尋樹具有如下特徵:
節點的左子樹只包含小於當前節點的數。
節點的右子樹只包含大於當前節點的數。
所有左子樹和右子樹自身必須也是二叉搜尋樹。
示例
輸入:
2
/ \
1 3
輸出: true
輸入:
5
/ \
1 4
/ \
3 6
輸出: false
解釋: 輸入為: [5,1,4,null,null,3,6]。
根節點的值為 5 ,但是其右子節點值為 4 。
解法一:遞迴
注意二叉搜尋樹的含義:每個節點的左子樹都小於節點值,每個節點的右子樹都大於節點值。
注意以下程式是錯的:
class Solution {
public boolean isValidBST(TreeNode root) {
if(root == null) return true;
if(root.left.val > root.val) return false;
if(root.right.val < root.val) return false;
return isValidBST(root.left) && isValidBST(root.right);
}
}
上面程式只檢驗了每個樹的左節點是否小於節點,右節點是否小於節點,比如示例2.不是二叉搜尋樹,但是會返回true。
每個子樹都滿足,說明中序遍歷的結果(左中右)是遞增的序列,所以只要判斷後一個序列比前一個序列大即可;中序遍歷可用遞迴或迭代法實現。
函式功能:判斷是否是二叉搜尋樹
1.終止條件:root == null, 返回true;
2.該做什麼:判斷當前節點和前面節點的值的大小,如果比之前的值小了就直接返回false;
3.什麼時候做:就是從中序遍歷的結果上比較大小的,中序。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
long pre = Long.MIN_VALUE; //先定義一個最小值,注意要在方法外,不然每次遞迴就又重置了。
public boolean isValidBST(TreeNode root) {
if(root == null) return true;
if(!isValidBST(root.left)) return false;
if(root.val <= pre) return false;
pre = root.val; //更新前一個元素的值;
return isValidBST(root.right);
}
}
空間複雜度:O(N):堆疊的支出
解法二:迭代
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
long pre = Long.MIN_VALUE;
public boolean isValidBST(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
while(!stack.isEmpty() || root != null){
if(root != null){
stack.push(root); //左邊界全部入棧;
root = root.left;
}else{
TreeNode top = stack.pop();
if(top.val <= pre){
return false;
}
root = top.right; //來到彈出節點的右節點;
pre = top.val; //更新上個元素的值;
}
}
return true;
}
}