美文网首页
leetcode :树(medium)

leetcode :树(medium)

作者: crazydane | 来源:发表于2017-05-31 23:18 被阅读0次

leetcode 98 Validate Binary Search Tree

Problem:

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

Binary tree [2,1,3], return true.
Example 2:

    1
   / \
  2   3

Binary tree [1,2,3], return false.

解题思路

一开始想当然用递归的思想,如果左子树的值小于根节点且同时又满足右子树的值大于根节点,就继续递归,否则返回false。代码如下。

public class Solution {
    public boolean isValidBST(TreeNode root) {
        if(root==null){
            return true;
        }
        if(root.left!=null && (root.left.val>root.val || !isValidBST(root.left))){
            return false;
        }
        
        if(root.right!=null && (root.right.val<root.val || !isValidBST(root.right))){
            return false;
        }
        return true;
    }
}```
但是运行后发现了问题。这段代码中我只关心了某一个节点是否符合要求。而纵观全局,所有的根节点右边的数字都应该大于根节点。思考之后,我设立一个取值范围,用于递归中。

public boolean isValidBST(TreeNode root) {
if(root==null)
return true;

return helper(root, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);

}

public boolean helper(TreeNode root, double low, double high){

if(root.val<=low || root.val>=high)
    return false;

if(root.left!=null && !helper(root.left, low, root.val)){
    return false;
}

if(root.right!=null && !helper(root.right, root.val, high)){
    return false;
}

return true;    

}

第三种方法写起来更简单,但是如果错误就发生在根节点附近,那它要慢于第二种的速度。

public boolean isValidBST(TreeNode root) {
return isValidBST(root, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
}

public boolean isValidBST(TreeNode p, double min, double max){
if(p==null)
return true;

if(p.val <= min || p.val >= max)
    return false;

return isValidBST(p.left, min, p.val) && isValidBST(p.right, p.val, max);

}

以上都是用的递归的思想来解决问题,现在利用广度优先遍历的思想来解决。
广度优先搜索算法需要用到队列。具体请参考以下链接:

public class Solution {
public boolean isValidBST(TreeNode root) {
if(root == null)
return true;
//利用一个队列来存储节点。
LinkedList<BNode> queue = new LinkedList<BNode>();
//初始化调用,根节点的取值范围是负无穷到正无穷
queue.add(new BNode(root, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
while(!queue.isEmpty()){
//从队列里弹出一个节点
BNode b = queue.poll();
if(b.n.val <= b.left || b.n.val >=b.right){
return false;
}
if(b.n.left!=null){
//添加一个新的节点。
queue.offer(new BNode(b.n.left, b.left, b.n.val));
}
if(b.n.right!=null){
queue.offer(new BNode(b.n.right, b.n.val, b.right));
}
}
return true;
}
}
//define a BNode class with TreeNode and it's boundaries
class BNode{
TreeNode n;
double left;
double right;
public BNode(TreeNode n, double left, double right){
this.n = n;
this.left = left;
this.right = right;
}
}


#leetcode 333 [Largest BST Subtree](https://leetcode.com/problems/largest-bst-subtree/)
#####Problem:
Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest means subtree with largest number of nodes in it.
Note:A subtree must include all of its descendants.Here's an example:
10
/ \

5 15
/ \ \
1 8 7

The Largest BST Subtree in this case is the highlighted one(5,1,8. The return value is the subtree's size, which is 3.
 
Hint:
You can recursively use algorithm similar to [98. Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/) at each node of the tree, which will result in O(nlogn) time complexity.

Follow up:Can you figure out ways to solve it with O(n) time complexity?  

class Wrapper{
int size;
int lower, upper;
boolean isBST;

public Wrapper(){
    lower = Integer.MAX_VALUE;
    upper = Integer.MIN_VALUE;
    isBST = false;
    size = 0;
}

}
public class Solution {
public int largestBSTSubtree(TreeNode root) {
return helper(root).size;
}

public Wrapper helper(TreeNode node){
    Wrapper curr = new Wrapper();

    if(node == null){
        curr.isBST= true;
        return curr;
    }

    Wrapper l = helper(node.left);
    Wrapper r = helper(node.right);

    //current subtree's boundaries
    curr.lower = Math.min(node.val, l.lower);
    curr.upper = Math.max(node.val, r.upper);

    //check left and right subtrees are BST or not
    //check left's upper again current's value and right's lower against current's value
    if(l.isBST && r.isBST && l.upper<=node.val && r.lower>=node.val){
        curr.size = l.size+r.size+1;
        curr.isBST = true;
    }else{
        curr.size = Math.max(l.size, r.size);
        curr.isBST  = false;
    }

    return curr;
}

}

相关文章

网友评论

      本文标题:leetcode :树(medium)

      本文链接:https://www.haomeiwen.com/subject/nlcjfxtx.html