nlgn就不说了。。说n的方法。

这个题做了好久。

一开始想到的是post-order traversal.

左右都是BST,然后自己也是BST,返还长度是左+右+自己(1)。

左右其中一个不是,或者自己不是的话,返还-1.

第一次尝试忽略了跳级问题,判断自己能不能和左右子树组成BST的情况是,自己必须比左子树的最大值大,比右子树的最小值小。。所以害的自己造个变量记录最大最小值。

提交的时候改了半天,主要问题在于更新最大最小但是会后,既要以子树更新,又要以自己的VAL更新,一开始忽略了其中一种。。

public class Solution
{ public class MaxMin
{
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
public MaxMin(int max, int min)
{
this.max = max;
this.min = min;
}
} int a = 1;
public int largestBSTSubtree(TreeNode root)
{ if(root == null) return 0;
MaxMin r = new MaxMin(Integer.MIN_VALUE,Integer.MAX_VALUE);
int res = helper(root,r); a = Math.max(res,a); return a; } public int helper(TreeNode root, MaxMin m)
{
if(root == null) return 0;
if(root.left == null && root.right == null)
{
m.max = Math.max(m.max,root.val);
m.min = Math.min(m.min,root.val);
return 1;
} MaxMin m1 = new MaxMin(m.max,m.min);
MaxMin m2 = new MaxMin(m.max,m.min); int left = helper(root.left,m1);
int right = helper(root.right,m2);
int res = 1; m.max = Math.max(m.max,root.val);
m.min = Math.min(m.min,root.val); m.max = Math.max(Math.max(m.max,m1.max),m2.max);
m.min = Math.min(Math.min(m.min,m1.min),m2.min); if(left != -1 && right != -1)
{ if(root.val < m2.min && root.val > m1.max)
{
res += left + right;
a = Math.max(res,a);
return res;
}
else return -1; }
else return -1; } }

另一种N的尝试是,做一个in-order traversal,找其中的递增组合。不过仔细想想犹豫结构不确定,不一定是completed tree所以无法判定。。



二刷。

这个题做了他妈好久。

回头看一刷觉得太繁琐了,肯定有问题,但是又不想在基础上改。

像题目说的,直白的做法是每个NODE都call一次valid BST,这样是O(nlgn).

现在要求O(n),只能遍历一次。那肯定是bottom-up,用post-order traversal.

有一点要注意的是,subtree得到底才行,必须包含最下的leaves.

我们需要传到上面的信息有这么几个:

  1. 我是不是BST,以便于上面判断他是不是BST.

  2. 我作为BST的最大Size,以便于上面进行左右取舍,或相加(如果左右+自己都是BST)

  3. 我的取值区间,最大值和最小值。对于上面的parent node来说,他得比左支最大值大,比右支最小值小。

需要传递的信息有3个,自己建个新的class比较方便。

学到的一个tricky是用size正负来表示1),是否是BST。负数就说明我不是BST。

Time: O(n) DFS post-order

Space: O(n) for Stack in memory

public class Solution {
public class Node {
int max;
int min;
int num;
public Node(int max, int min, int num) {
this.max = max;
this.min = min;
this.num = num;
}
} public int largestBSTSubtree(TreeNode root) {
return Math.abs(dfs(root).num);
} public Node dfs(TreeNode root) {
if (root == null) return new Node(Integer.MIN_VALUE, Integer.MAX_VALUE, 0); Node leftRes = dfs(root.left);
Node rightRes = dfs(root.right); int curMin = Math.min(root.val, leftRes.min);
int curMax = Math.max(root.val, rightRes.max); if (root.val <= leftRes.max || root.val >= rightRes.min || leftRes.num < 0 || rightRes.num < 0) {
//System.out.println(leftRes.num + " " + rightRes.num);
return new Node(curMax, curMin, Math.max(Math.abs(leftRes.num), Math.abs(rightRes.num)) * -1);
} else {
return new Node(curMax, curMin, leftRes.num + rightRes.num + 1);
} }
}

2个判断不太好理解,着重说一下。

    if (root.val <= leftRes.max || root.val >= rightRes.min || leftRes.num < 0 || rightRes.num < 0) {
return new Node(curMax, curMin, Math.max(Math.abs(leftRes.num), Math.abs(rightRes.num)) * -1);
}

这说明不符合BST规定。

root.val <= 左支最大值. root.val >= 右支最小值.

左支BST的SIZE < 0 或者 右支BST的Size < 0

这个时候返还的Node要注意。

curMax和curMin说实话其实无所谓,返还什么都行,因为第三个值要返还负数。

第三个值首先要确定返还负数,最后乘以-1。

判断前取绝对值Math.abs(leftRes.num)是代表:

子树最大subTree的size,不一定就是root.left的值,可能还要往下。

正负号代表当前子树(root.left)是否是BST.

else是判断成功,左右都是,自己也是,那么显然左+右+1就行了。

333. Largest BST Subtree的更多相关文章

  1. [LeetCode] 333. Largest BST Subtree 最大的二分搜索子树

    Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest mea ...

  2. 333. Largest BST Subtree节点数最多的bst子树

    [抄题]: Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where large ...

  3. [leetcode]333. Largest BST Subtree最大二叉搜索树子树

    Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest mea ...

  4. LeetCode 333. Largest BST Subtree

    原题链接在这里:https://leetcode.com/problems/largest-bst-subtree/ 题目: Given a binary tree, find the largest ...

  5. 【LeetCode】333. Largest BST Subtree 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS 日期 题目地址:https://leetcod ...

  6. [LeetCode] Largest BST Subtree 最大的二分搜索子树

    Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest mea ...

  7. Largest BST Subtree

    Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest mea ...

  8. Leetcode: Largest BST Subtree

    Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest mea ...

  9. [Locked] Largest BST Subtree

    Largest BST Subtree Given a binary tree, find the largest subtree which is a Binary Search Tree (BST ...

随机推荐

  1. throw 导致 Error C2220, wraning C4702错误

    今天在程序加了一个语句,发现报 Error C2220, Wraning C4702错误 查询Wraning C4702 ,[无法访问的代码] 由于为 Visual Studio .NET 2003 ...

  2. Proxy 模式

    在以下集中情况下可以用 Proxy模式解决问题: 1)创建开销大的对象时候,比如显示一幅大的图片,我们将这个创建的过程交给代理去完成,GoF 称之为虚代理(Virtual Proxy): 2)为网络上 ...

  3. C# ToString常用技巧总结

    ToString是在开发中最常用的操作,其作用是将其它类型以字符串类型表示.例如: int i=2;i.ToString() //”2″Object o = new Object();o.ToStri ...

  4. PHP时间戳和日期相互转换

    在php中我们要把时间戳转换日期可以直接使用date函数来实现,如果要把日期转换成时间戳可以使用strtotime()函数实现,下面我来给大家举例说明. 1.php中时间转换函数 strtotime ...

  5. 入门1:PHP的优点

    一.语法简单 二.学习成本低 (因为语法简单 所以学习成本低) 三.开发效率高 (PHP运行流程很简单,语法也很简单,必然开发效率就高) 四.跨平台 (我们只需要写一份PHP的程序,就可以非常方便的把 ...

  6. dedecms织梦导航栏二级菜单的实现方法

    dede导航下拉菜单,一级栏目增加二级下拉菜单   使用dedecms5.6——5.7 将这段代码贴到templets\default\head.htm文件里<!-- //二级子类下拉菜单,考虑 ...

  7. python str + int

    TypeError: cannot concatenate 'str' and 'int' objects 1. print 'Is your secret number " + str(p ...

  8. JAVA线程示范之一种

    线程有两种方法生成,这是其中的一种.. MyRunnable.java public class MyRunnable implements Runnable { public void run() ...

  9. github 托管代码两分钟教程【转载,亲测可行】

    http://blog.csdn.net/duxinfeng2010/article/details/8654690 出自以上地址 本篇文章介绍的是如何将工程代码托管到上面:如果你还没注册GitHub ...

  10. BAT互联网公司是如何内部推荐的?

    中国十大互联网公司 注:以上按照目前市值排序整理出来,当然还有更多未上市的潜力股.如:美团.豆瓣.豌豆荚.美图秀秀等等 各大互联网公司招聘官网 阿里招聘:https://job.alibaba.com ...