333. Largest BST Subtree
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.
我们需要传到上面的信息有这么几个:
我是不是BST,以便于上面判断他是不是BST.
我作为BST的最大Size,以便于上面进行左右取舍,或相加(如果左右+自己都是BST)
我的取值区间,最大值和最小值。对于上面的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的更多相关文章
- [LeetCode] 333. Largest BST Subtree 最大的二分搜索子树
Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest mea ...
- 333. Largest BST Subtree节点数最多的bst子树
[抄题]: Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where large ...
- [leetcode]333. Largest BST Subtree最大二叉搜索树子树
Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest mea ...
- LeetCode 333. Largest BST Subtree
原题链接在这里:https://leetcode.com/problems/largest-bst-subtree/ 题目: Given a binary tree, find the largest ...
- 【LeetCode】333. Largest BST Subtree 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS 日期 题目地址:https://leetcod ...
- [LeetCode] Largest BST Subtree 最大的二分搜索子树
Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest mea ...
- Largest BST Subtree
Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest mea ...
- Leetcode: Largest BST Subtree
Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest mea ...
- [Locked] Largest BST Subtree
Largest BST Subtree Given a binary tree, find the largest subtree which is a Binary Search Tree (BST ...
随机推荐
- >/dev/null 2>&1 这句话的含义
1表示标准输出,2表示标准错误输出 2>&1表示将标准错误输出重定向到标准输出,这样,程序或者命令的正常输出和错误输出就可以在标准输出输出(也就是一起输出). 一般来讲标准输出和标准错误 ...
- ip接口调用
<?php header("Content-type: text/html; charset=utf-8"); function getIP(){ if (isset($_S ...
- java——输入流FileInputStream
写一个简单的程序,实现从电脑中的一个盘里的文件中往程序中输入内容. package com.liaojianya.chapter5; import java.io.FileInputStream; i ...
- java常用指令
javac 编译java源文件到字节码文件 -d XXX 1.指定编译后的字节码文件存放位置. 2.若编译的java源文件中使用包名,则根据包名生成相应的子目录 javac -d . Hello.ja ...
- SGU 164.Airline(结论题)
时间限制:0.25s 空间限制:4M 题意: 在n(1<=n<=200)个点的无向完全图中,有m种不同的边.现在从中选择不超过(m+1)/2种边,使得任意两点可以通过不超过3条边互相到达. ...
- Oracle数据库之视图与索引
Oracle数据库之视图与索引 1. 视图简介 视图是基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改. 视图基于的表称为基表,视图是存储在数据字典里的一条SE ...
- windows 下 pgsql 拓展开启
环境:windowxp + apache2.2+php5.2.13+postgresql8.3 操作步骤:1.修改php.ini,去掉“extension=php_pgsql.dll ”和“exten ...
- Laravel框架——增删改查
增: //save返回true false $res = new member(); res->username = 'a'; $res->password = 'b'; dd($res- ...
- js 返回前一页并刷新页面方法
[导读] 要返回上一页再刷新页面我们用到最多的是在像php,asp,jsp,asp.net中,下面我来给大家先介绍js 返回前一页并刷新页面,然后再把这些代码放在php中实现删除后返回当前页面并刷新页 ...
- Java实现Qt的SIGNAL-SLOT机制
SIGNAL-SLOT是Qt的一大特色,使用起来十分方便.在传统的AWT和Swing编程中,我们都是为要在 监听的对象上添加Listener监听器.被监听对象中保存有Listener的列表,当相关事件 ...