给定一个二叉树,编写一个函数,该函数返回最大子树的大小,该子树也是一个二叉搜索树(BST)。如果完整的二叉树是BST,则返回整个树的大小。
例子:
Input:
5
/ \
2 4
/ \
1 3
Output: 3
The following subtree is the
maximum size BST subtree
2
/ \
1 3
Input:
50
/ \
30 60
/ \ / \
5 20 45 70
/ \
65 80
Output: 5
The following subtree is the
maximum size BST subtree
60
/ \
45 70
/ \
65 80
建议:在继续解决方案之前,请先在“实践”上解决它。
我们在下面的文章中讨论了两种方法。
在给定的二叉树中找到最大的BST子树|套装1
在这篇文章中,讨论了一个不同的O(n)解决方案。该解决方案比上面讨论的解决方案更简单,并且可以在O(n)时间内工作。
这个想法基于检查二进制树是否为BST文章的方法3。
如果对每个节点x都遵循true,则树为BST。
- (x的)左子树中的最大值小于x的值。
- (x的)右子树中的最小值大于x的值。
我们以自下而上的方式遍历树。对于每个遍历的节点,我们在以其为根的子树中返回最大值和最小值。如果任何节点遵循上述属性和大小
C++
// C++ program to find largest BST in a
// Binary Tree.
#include
using namespace std;
/* A binary tree node has data,
pointer to left child and a
pointer to right child */
struct Node
{
int data;
struct Node* left;
struct Node* right;
};
/* Helper function that allocates a new
node with the given data and NULL left
and right pointers. */
struct Node* newNode(int data)
{
struct Node* node = new Node;
node->data = data;
node->left = node->right = NULL;
return(node);
}
// Information to be returned by every
// node in bottom up traversal.
struct Info
{
int sz; // Size of subtree
int max; // Min value in subtree
int min; // Max value in subtree
int ans; // Size of largest BST which
// is subtree of current node
bool isBST; // If subtree is BST
};
// Returns Information about subtree. The
// Information also includes size of largest
// subtree which is a BST.
Info largestBSTBT(Node* root)
{
// Base cases : When tree is empty or it has
// one child.
if (root == NULL)
return {0, INT_MIN, INT_MAX, 0, true};
if (root->left == NULL && root->right == NULL)
return {1, root->data, root->data, 1, true};
// Recur for left subtree and right subtrees
Info l = largestBSTBT(root->left);
Info r = largestBSTBT(root->right);
// Create a return variable and initialize its
// size.
Info ret;
ret.sz = (1 + l.sz + r.sz);
// If whole tree rooted under current root is
// BST.
if (l.isBST && r.isBST && l.max < root->data &&
r.min > root->data)
{
ret.min = min(l.min, min(r.min, root->data));
ret.max = max(r.max, max(l.max, root->data));
// Update answer for tree rooted under
// current 'root'
ret.ans = ret.sz;
ret.isBST = true;
return ret;
}
// If whole tree is not BST, return maximum
// of left and right subtrees
ret.ans = max(l.ans, r.ans);
ret.isBST = false;
return ret;
}
/* Driver program to test above functions*/
int main()
{
/* Let us construct the following Tree
60
/ \
65 70
/
50 */
struct Node *root = newNode(60);
root->left = newNode(65);
root->right = newNode(70);
root->left->left = newNode(50);
printf(" Size of the largest BST is %d\n",
largestBSTBT(root).ans);
return 0;
}
// This code is contributed by Vivek Garg in a
// comment on below set 1.
// www.geeksforgeeks.org/find-the-largest-subtree-in-a-tree-that-is-also-a-bst/
Java
// Java program to find largest BST in a
// Binary Tree.
import java.io.*;
import java.math.*;
import java.util.*;
/* A binary tree node has data,
pointer to left child and a
pointer to right child */
class Node {
int data;
Node left, right;
public Node(int d){
data = d;
left = right = null;
}
}
class GFG
{
public static void main (String[] args)
{
Node node = new Node(60);
node.left = new Node(65);
node.right = new Node(70);
node.left.left = new Node(50);
System.out.println("Size of the largest BST is " +
Solution.largestBst(node)+ "\n");
}
}
class Solution
{
static int MAX = Integer.MAX_VALUE;
static int MIN = Integer.MIN_VALUE;
static class nodeInfo
{
int size; // Size of subtree
int max; // Min value in subtree
int min; // Max value in subtree
int ans; // Size of largest BST which
// is subtree of current node
boolean isBST; // If subtree is BST
nodeInfo(){} // empty constructor
nodeInfo(int size, int max, int min,
int ans, boolean isBST)
{
this.size = size;
this.max = max;
this.min = min;
this.ans = ans;
this.isBST = isBST;
}
}
static nodeInfo largestBST(Node root)
{
// Base cases : When tree is empty or it has
// one child.
if(root == null)
return new nodeInfo(0, MIN, MAX, 0, true);
if(root.left == null && root.right == null)
return new nodeInfo(1, root.data, root.data, 1, true);
// Recur for left subtree and right subtrees
nodeInfo left = largestBST(root.left);
nodeInfo right = largestBST(root.right);
// Create a return variable and initialize its size.
nodeInfo returnInfo = new nodeInfo();
returnInfo.size = 1 + left.size + right.size;
// If whole tree rooted under current root is BST.
if(left.isBST && right.isBST
&& left.max < root.data
&& right.min > root.data)
{
returnInfo.min = Math.min(Math.min(left.min, right.min), root.data);
returnInfo.max = Math.max(Math.max(left.max, right.max), root.data);
// Update answer for tree rooted under
// current 'root'
returnInfo.ans = returnInfo.size;
returnInfo.isBST = true;
return returnInfo;
}
// If whole tree is not BST, return maximum
// of left and right subtrees
returnInfo.ans = Math.max(left.ans, right.ans);
returnInfo.isBST = false;
return returnInfo;
}
// Return the size of the largest sub-tree which is also a BST
static int largestBst(Node root)
{
return largestBST(root).ans;
}
}
// This code is contributed by Ayush Choudhary
Python3
# Python program to find largest
# BST in a Binary Tree.
INT_MIN = -2147483648
INT_MAX = 2147483647
# Helper function that allocates a new
# node with the given data and None left
# and right pointers.
class newNode:
# Constructor to create a new node
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# Returns Information about subtree. The
# Information also includes size of largest
# subtree which is a BST
def largestBSTBT(root):
# Base cases : When tree is empty or it has
# one child.
if (root == None):
return 0, INT_MIN, INT_MAX, 0, True
if (root.left == None and root.right == None) :
return 1, root.data, root.data, 1, True
# Recur for left subtree and right subtrees
l = largestBSTBT(root.left)
r = largestBSTBT(root.right)
# Create a return variable and initialize its
# size.
ret = [0, 0, 0, 0, 0]
ret[0] = (1 + l[0] + r[0])
# If whole tree rooted under current root is
# BST.
if (l[4] and r[4] and l[1] <
root.data and r[2] > root.data) :
ret[2] = min(l[2], min(r[2], root.data))
ret[1] = max(r[1], max(l[1], root.data))
# Update answer for tree rooted under
# current 'root'
ret[3] = ret[0]
ret[4] = True
return ret
# If whole tree is not BST, return maximum
# of left and right subtrees
ret[3] = max(l[3], r[3])
ret[4] = False
return ret
# Driver Code
if __name__ == '__main__':
"""Let us construct the following Tree
60
/ \
65 70
/
50 """
root = newNode(60)
root.left = newNode(65)
root.right = newNode(70)
root.left.left = newNode(50)
print("Size of the largest BST is",
largestBSTBT(root)[3])
# This code is contributed
# Shubham Singh(SHUBHAMSINGH10)
输出
Size of the largest BST is 2
输出:
Size of largest BST is 2