333. 最大BST子树

  1. 最大BST子树

    文章目录

思路

  • 此题采用自底向上的思想,只有左右子树都为BST(包含null),那么其以root为根节点的二叉树才能是BST
  • 这里想到后序遍历(左右根)
  • 注意:有一种情况以root为根节点的二叉树不是BST,那么所求的BST一定在较矮的子树中,这里设置了 leftBSTSize = -1, rightBSTSize= -1,作为哨兵,如果root的左右子树都为BST(包含null),那么leftBSTSize, rightBSTSize 一定大于等于0

Solution

public class _333_最大BST子树 {

	public int largeBSTSubtree(TreeNode root){
		return (root == null) ? 0 : getInfo(root).size;
	}

	// 返回root为根节点的二叉树的最大BST子树信息
	public Info getInfo(TreeNode root) {
		if ( root == null ) return null;
		// 左右子树信息
		Info li = getInfo(root.left);
		Info ri = getInfo(root.right);

		/**
		有4种情况,以root为根节点的二又树就是一棵BST,最大BST子树就是其本身
		① li != null && ri != null
		&& li.root == root.left && root.val > 1i.max
		&& ri.root == root.right && root.val < ri.min

		② li != nu1l && ri == nu11
		&& 11.root == root.left && root.val > 1i.max

		③ 1i == nu11 && ri != nu11
		&& ri.root == root.right && root.val < ri.min

		④ 1i == nu11 && ri == nu11
		*/

		int leftBSTSize = -1, rightBSTSize= -1 , max = root.val, min = root.val;
		if (li == null){
			leftBSTSize = 0;
		}else if (li.root == root.left && li.max < root.val){
			leftBSTSize = li.size;
			min =  li.min; 
		}

		if (ri == null){ // 右子树为空
			rightBSTSize = 0;
		}else if (ri.root == root.right && ri.min > root.val){ // 右子树不为空,且满足根节点的第一个右节点就为BST
			rightBSTSize = ri.size;
			max = ri.max;
		}
		 
		// 以root为根的二叉树是BST
		if (leftBSTSize != -1 && rightBSTSize != -1){
			return new Info(root,1+li.size+ri.size,max,min)
		}

		// 均不为-1,即左右子树存在,但以root作为根的二叉树不是BST
		// BST可能就是在较矮的子树中
		if(li!=null && ri != null) return (li.size > ri.size) ? li :ri;

		// 返回li、ri中不为null的那个Info
		return (li!= null) ? li:ri;
	}


	private static class Info {
		public TreeNode root;
		public int size;
		public int max;
		public int min;

		public Info(TreeNode root, int size, int max, int min){
			this.root =root;
			this.size =size;
			this.max = max;
			this.min = min;
		}
	}
}

Reference:小码哥MJ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值