题目
面试题 04.05. 合法二叉搜索树
实现一个函数,检查一棵二叉树是否为二叉搜索树。
示例 1:
输入:
2
/ \
1 3
输出: true
示例 2:
输入:
5
/ \
1 4
/ \
3 6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
根节点的值为 5 ,但是其右子节点值为 4 。
思路1:
二叉树的前序遍历(递归法)
我们可以把这个问题拆分成小问题,
-
那么对于每一个节点来说,它要符合二叉搜索树是有一个值的区间范围的,假设范围为(lower,upper)
-
它自身在这个范围内,且它的左子树和右子树都为二叉搜索树,那么它以及它的子节点就是二叉搜索树
-
然后我们就可以分别再去分析它的左子节点和右子节点,直接分析到叶子节点为止
-
叶子节点的子节点为空,那么也是符合二叉搜索树的,所以跳出递归的条件也有了,就是root==null,则return true
-
初始时,对于根节点来说,lower和upper分别为,-Infinity和Infinity,那么起始条件也有了
代码如下:
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isValidBST = function(root) {
return isBST(root,-Infinity,Infinity)
};
function isBST(root,lower,upper){
if(!root) return true;
if(root.val<=lower || root.val >= upper) return false;
return isBST(root.left,lower,root.val) && isBST(root.right,root.val,upper)
}
复杂度分析:
时间复杂度:O(n),n为二叉树节点的数量,因为每个节点都会被遍历一次。
空间复杂度:O(n),递归函数在递归的过程中,需要为每一层额外分配栈空间,那么空间复杂度与二叉树的高度成正比,最坏情况下,二叉树是一条链表,那么高度就是n。
思路2:
对于一个二叉搜索树,中序遍历的结果刚好是一个递增序列,可以从这个思路下手。
- 中序遍历这个颗二叉树,如果当前值小于下一个值则为二叉搜索树。否则不是。
代码如下:
function isValidBST (root) {
let stack = [];
let prev = -Infinity;
while (stack.length || root) {
while (root) {
stack.push(root);
root = root.left;
}
root = stack.pop();
// 如果中序遍历得到的节点的值小于等于前一个 prev,说明不是二叉搜索树
if (root.val <= prev) {
return false;
}
prev = root.val;
root = root.right;
}
return true;
}