Largest BST in a Binary Tree

15 篇文章 0 订阅

一到面试题,挺有意思的。

简单做法是对于每个node都进行一遍isBST的测试,找出最大的那个。

public static int largestBSTNaive(TreeNode root){
		if(isBST(root)){
			return size(root);
		}
		return Math.max(largestBSTNaive(root.left), largestBSTNaive(root.right));
	}

	private static int size(TreeNode root) {
		if(root == null)
			return 0;
		return 1 + size(root.left) + size(root.right);
	}

	private static boolean isBST(TreeNode root) {
		
		return isBST(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
	}
	
	private static boolean isBST(TreeNode root, int min, int max) {
		if(root == null)
			return true;
		if(root.val >= max)
			return false;
		else if(root.val <= min)
			return false;
		
		return isBST(root.left, min, root.val) && isBST(root.right, root.val, max);
	}

上面的做法是top-down的访问,其实可以用bottom-up的方法,根据左子树和右子树返回的信息就可以判断当前子树是不是BST。每个子树需要返回的信息有三个:

1. 子树是不是BST

2.MAX VALUE in this sub tree

3.min value in this sub tree

首先递归得到左右子树的结果,然后如果当前node.val>left.max&&node.val<right.min,切左右子树都是BST,则已当前node为根的子树也是BST。

private static int res = 0;
	public static int largestBSTBetter(TreeNode root){
		largestBSTHelper(root);
		return res;
	}
	
	private static Data largestBSTHelper(TreeNode root){
		Data curr = new Data();
		if(root == null){
			curr.isBST = true;
			curr.size = 0;
			return curr;
		}
		
		Data left = largestBSTHelper(root.left);
		Data right = largestBSTHelper(root.right);
		
		curr.min = Math.min(root.val, Math.min(right.min,left.min));
		curr.max = Math.max(root.val, Math.max(right.max, left.max));
		if(left.isBST && root.val > left.max && right.isBST && root.val < right.min){
			curr.isBST = true;
			curr.size = 1 + left.size + right.size;
			if(curr.size > res)
				res = curr.size;
		}
		else{
			curr.size = 0;
		}
		return curr;
	}
}


class Data{
	boolean isBST = false;
	//the minimum for right sub tree or the maximum for right sub tree
	int min = Integer.MAX_VALUE;
	int max = Integer.MIN_VALUE;
	//if the tree is BST, size is the size of the tree; otherwise zero
	int size;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值