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

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. 
The return value is the subtree‘s size, which is 3.

Hint:

  1. You can recursively use algorithm similar to 98. 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?

这道题让我们求一棵二分树的最大二分搜索子树,所谓二分搜索树就是满足左<根<右的二分树,我们需要返回这个二分搜索子树的节点个数。题目中给的提示说我们可以用之前那道Validate Binary Search Tree的方法来做,时间复杂度为O(nlogn),这种方法是把每个节点都当做根节点,来验证其是否是二叉搜索数,并记录节点的个数,若是二叉搜索树,就更新最终结果,参见代码如下:

解法一:

class Solution {
public:
    int largestBSTSubtree(TreeNode* root) {
        int res = 0;
        dfs(root, res);
        return res;
    }
    void dfs(TreeNode *root, int &res) {
        if (!root) return;
        int d = countBFS(root, INT_MIN, INT_MAX);
        if (d != -1) {
            res = max(res, d);
            return;
        }
        dfs(root->left, res);
        dfs(root->right, res);
    }
    int countBFS(TreeNode *root, int mn, int mx) {
        if (!root) return 0;
        if (root->val < mn || root->val > mx) return -1;
        int left = countBFS(root->left, mn, root->val);
        if (left == -1) return -1;
        int right = countBFS(root->right, root->val, mx);
        if (right == -1) return -1;
        return left + right + 1;
    }
};

题目中的Follow up让我们用O(n)的时间复杂度来解决问题,我们还是采用DFS的思想来解题,由于时间复杂度的限制,只允许我们遍历一次整个二叉树,由于满足题目要求的 二叉搜索子树必定是有叶节点的,所以我们的思路就是先递归到最左子节点,然后逐层往上递归,对于每一个节点,我们都记录当前最大的BST的节点数,当做为左子树的最大值,和做为右子树的最小值,当每次遇到左子节点不存在或者当前节点值大于左子树的最大值,且右子树不存在或者当前节点值小于右子树的最小数时,说明BST的节点数又增加了一个,我们更新结果及其参数,如果当前节点不是BST的节点,那么我们更新BST的节点数res为左右子节点的各自的BST的节点数的较大值,参见代码如下:

解法二:

class Solution {
public:
    int largestBSTSubtree(TreeNode* root) {
        int res = 0, mn = INT_MIN, mx = INT_MAX;
        bool d = isValidBST(root, mn, mx, res);
        return res;
    }
    bool isValidBST(TreeNode *root, int &mn, int &mx, int &res) {
        if (!root) return true;
        int left_n = 0, right_n = 0, left_mn = INT_MIN;
        int right_mn = INT_MIN, left_mx = INT_MAX, right_mx = INT_MAX;
        bool left = isValidBST(root->left, left_mn, left_mx, left_n);
        bool right = isValidBST(root->right, right_mn, right_mx, right_n);
        if (left && right) {
            if ((!root->left || root->val >= left_mx) && (!root->right || root->val <= right_mn)) {
                res = left_n + right_n + 1;
                mn = root->left ? left_mn : root->val;
                mx = root->right ? right_mx : root->val;
                return true;
            }
        }
        res = max(left_n, right_n);
        return false;
    }
};

类似题目:

Validate Binary Search Tree

参考资料:

https://leetcode.com/discuss/85959/12ms-c-solution

https://leetcode.com/discuss/86015/two-dfs-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

时间: 2024-12-24 21:24:21

[LeetCode] Largest BST Subtree 最大的二分搜索子树的相关文章

LeetCode Largest BST Subtree

原题链接在这里:https://leetcode.com/problems/largest-bst-subtree/ 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 desce

333.Largest BST Subtree

/* * 333.Largest BST Subtree * 2016-3-27 by Mingyang * 这个题目我的思路,自底向上的方法非常正确的!但是,这个题目独特的一点就在于对于一个 * Tree是不是BST得判断,他必须表示对左子树的最大的还大,右子树的最小的还要小,所以这样看来就是 * 必须要保证root必须保存当前子树1.isBST?2.left smallest.3.right biggest.4.node number * 可以先建一个class,也可以做一个array */

[LeetCode] Count Univalue Subtrees 计数相同值子树的个数

Given a binary tree, count the number of uni-value subtrees. A Uni-value subtree means all nodes of the subtree have the same value. For example:Given binary tree, 5 / 1 5 / \ 5 5 5 return 4. 这道题让我们求相同值子树的个数,就是所有节点值都相同的子树的个数,之前有道求最大BST子树的题Largest BST

(每日算法)Leetcode -- Largest Rectangle in Histogram(最大实心矩形)

思路:如果时间复杂度要求是O(n 2 )的话,解法比较多也比较好理解.比如可以遍历,对于当前 i 位置上的立柱,计算出以这个i 立柱结尾的最大矩形,然后求出总的最大矩形. Given  n  non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. Above

LeetCode: Largest Rectangle in Histogram [084]

[题目] Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]. The lar

LeetCode &quot;Largest Rectangle in Histogram&quot; - TRICKY MONO-QUEUE

I got a DP solution first which is O(n^2). Apparently it is not a optimized one - think about: it is linear value space. There must be O(n) solution. And yes there is: http://fisherlei.blogspot.com/2012/12/leetcode-largest-rectangle-in-histogram.html

[LeetCode] Most Frequent Subtree Sum 出现频率最高的子树和

Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent

LeetCode 235 BST的最近公共祖先

这个题目比一般二叉树的最近公共祖先更佳的具体化,因为左右遍历路径都可以提前确定. 由于BST TREE的特点 1.当p,q节点在root的不同子树上的时候,root就位根节点 2.p或者q就是root的时候,返回root 3.p,q同时在root的左子树或者右子树,那么就递归遍历左子树或者右子树 1 TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 2 while( (root->val - p-

[LeetCode]Largest Rectangle in Histgram,解题报告

目录 目录 题目 思路一 思路二 题目 Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. Above is a histogram where width of each bar is 1, given height = [2,1,5,