Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
- The left subtree of a node contains only nodes with keys less than the node's key.
- The right subtree of a node contains only nodes with keys greater than the node's key.
- Both the left and right subtrees must also be binary search trees.
Example 1:
2 / \ 1 3 Input: [2,1,3] Output: trueExample 2:
5 / \ 1 4 / \ 3 6 Input: [5,1,4,null,null,3,6] Output: false Explanation: The root node's value is 5 but its right child's value is 4.
最直观的方法是遍历顺便在BST中每一个查找元素,需要一个hashmap防止重复,代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
TreeNode r=null;
Map<Integer,Boolean> hash=null;
{
hash=new HashMap<Integer,Boolean>();
}
public boolean isValidBST(TreeNode root) {
if(root==null){return true;}
if(r==null){r=root;}
if(hash.get(root.val)==null){hash.put(root.val,true);}
else return false;
return find(r,root.val)&&isValidBST(root.left)&&isValidBST(root.right);
}
public boolean find(TreeNode node, int target){
if(node==null){return false;}
if(node.val==target){return true;}
else if(node.val>target){return find(node.left,target);}
else return find(node.right,target);
}
}
速度是2ms,不算快,而且哈希表会占用额外空间。
第二种方法是设置上下界,访问左节点更新上界为节点值,访问右节点更新下界为节点值,代码(分别为递归和循环方式):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isValidBST(TreeNode root) {
return bst2(root,null,null);
}
public boolean bst2(TreeNode node,Integer min,Integer max){
if(node==null) return true;
if(min!=null&&min>=node.val) return false;
if(max!=null&&max<=node.val) return false;
return bst2(node.right,node.val,max)&&bst2(node.left,min,node.val);
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
LinkedList<TreeNode> stack = new LinkedList();
LinkedList<Integer> maxs = new LinkedList(),mins = new LinkedList();
public void update(TreeNode node,Integer max,Integer min){
stack.add(node);
maxs.add(max);
mins.add(min);
}
public boolean isValidBST(TreeNode root) {
Integer min=null;
Integer max=null;
update(root,max,min);
while(!stack.isEmpty()){
root=stack.poll();
min=mins.poll();
max=maxs.poll();
if(root==null){continue;}
if(min!=null&&root.val<=min){return false;}
if(max!=null&&root.val>=max){return false;}
update(root.left,root.val,min);
update(root.right,max,root.val);
}
return true;
}
}
递归还满快的0ms,但是循环就比较慢了,操作三个链表还是费时间。
最后才是BST的真正性质,中序DFS时各个节点值是按从小到大排序的,代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
Integer last=null;
public boolean isValidBST(TreeNode root) {
if(root==null){return true;}
boolean l=isValidBST(root.left);
if(last!=null&&root.val<=last){return false;}
last=root.val;
boolean r=isValidBST(root.right);
return l&&r;
}
}
0ms