给定一颗二叉树,已知其中所有节点的值都不一样,找到含有节点最多的搜索二叉子树,输出该子树总节点的数量。
搜索二叉树是指对于二叉树的任何一个节点,都大于其左子树中的全部节点,但是小于其右子树中的全部节点。
第一行输入两个整数 n 和 root,n 表示二叉树的总节点个数,root 表示二叉树的根节点。
以下 n 行每行三个整数 fa,lch,rch,表示 fa 的左儿子为 lch,右儿子为 rch。(如果 lch 为 0 则表示 fa 没有左儿子,rch同理)
ps:节点的编号就是节点的值。
3 2 2 1 3 1 0 0 3 0 0
3
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.HashMap;
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
class Info {
public TreeNode maxBSTHead;
public int maxBSTSize;
public boolean isBST;
public int min;
public int max;
public Info(TreeNode maxBSTHead, int maxBSTSize, boolean isBST, int min, int max) {
this.maxBSTHead = maxBSTHead;
this.maxBSTSize = maxBSTSize;
this.isBST = isBST;
this.min = min;
this.max = max;
}
}
public class Main{
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
HashMap<Integer, TreeNode> map = new HashMap<>();
String[] params = br.readLine().split(" ");
int n = Integer.parseInt(params[0]), rootVal = Integer.parseInt(params[1]);
// 构建二叉树
TreeNode root = new TreeNode(rootVal);
map.put(rootVal, root);
for(int i = 0; i < n; i++){
params = br.readLine().split(" ");
int nodeVal = Integer.parseInt(params[0]);
int leftVal = Integer.parseInt(params[1]);
int rightVal = Integer.parseInt(params[2]);
TreeNode node = map.get(nodeVal);
if(leftVal != 0) {
node.left = new TreeNode(leftVal);
map.put(leftVal, node.left);
}
if(rightVal != 0) {
node.right = new TreeNode(rightVal);
map.put(rightVal, node.right);
}
}
// 求解
System.out.println(process(root).maxBSTSize);
}
private static Info process(TreeNode node) {
if(node == null) return null;
Info leftInfo = process(node.left);
Info rightInfo = process(node.right);
TreeNode maxBSTHead = null;
int maxBSTSize = 0;
int max = node.val;
int min = node.val;
// 最值在左右信息不为空的时候需要比较更新
if(leftInfo != null){
maxBSTHead = leftInfo.maxBSTHead;
maxBSTSize = leftInfo.maxBSTSize;
max = Math.max(max, leftInfo.max);
min = Math.min(min, leftInfo.min);
}
if(rightInfo != null){
if(rightInfo.maxBSTSize > maxBSTSize){
maxBSTHead = rightInfo.maxBSTHead;
maxBSTSize = rightInfo.maxBSTSize;
}
max = Math.max(max, rightInfo.max);
min = Math.min(min, rightInfo.min);
}
boolean isBST = false;
// 左右子树都是BST且能够和当前节点连起来时,能够形成一个以当前节点为根的更大的BST
if((leftInfo == null || (leftInfo.isBST && leftInfo.max < node.val)) && (rightInfo == null || (rightInfo.isBST && rightInfo.min > node.val))){
isBST = true;
maxBSTHead = node;
maxBSTSize = (leftInfo != null? leftInfo.maxBSTSize: 0) + (rightInfo != null? rightInfo.maxBSTSize: 0) + 1;
}
return new Info(maxBSTHead, maxBSTSize, isBST, min, max);
}
} 很好理解,但是时间复杂度比较高
import java.util.HashMap;
import java.util.Scanner;
/**
* @Author fgf
* @create 2020/3/10 22:12
* 找到二叉树中的最大搜索二叉之树
*/
class Node {
public int value;
public Node left;
public Node right;
public Node(int data){
this.value = data;
}
}
public class Main {
private static Node bstNode = null;
private static int max = Integer.MIN_VALUE;
private static int pre = Integer.MIN_VALUE;
public static void getMaxBST(Node root){
if(root == null)
return;
pre = Integer.MIN_VALUE;
if(isBST(root)){
int nodesNum = getNodesNum(root);
if(nodesNum > max){
max = nodesNum;
bstNode = root;
}
}
getMaxBST(root.left);
getMaxBST(root.right);
}
//获得二叉树节点个数
public static int getNodesNum(Node root){
if(root == null)
return 0;
return 1 + getNodesNum(root.left) + getNodesNum(root.right);
}
//判断是否是一颗搜索二叉树 中序遍历 左中右
public static boolean isBST(Node root){
if(root == null)
return true;
boolean flagLeft = isBST(root.left);
if(pre >= root.value)
return false;
pre = root.value;
if(flagLeft == false)
return false;
else
return isBST(root.right);
}
public static void main(String[] args) {
/**
13 6
6 1 12
1 -1 3
12 10 13
-1 0 0
3 0 0
10 4 14
13 20 16
4 2 5
14 11 15
2 0 0
5 0 0
11 0 0
15 0 0
*/
Scanner scanner = new Scanner(System.in);
int count = scanner.nextInt();
Node root = new Node(scanner.nextInt());
HashMap<Integer, Node> hashMap = new HashMap<>();
hashMap.put(root.value, root);
int[][] nodes = new int[count][3];
for(int i=0; i<count; i++){
for(int j=0; j<3; j++){
int v = scanner.nextInt();
if(v != 0)
hashMap.put(v, new Node(v));
nodes[i][j] = v;
}
}
for(int i=0; i<count; i++){
int[] arr = nodes[i];
Node fakeRoot = hashMap.get(arr[0]);
if(arr[1] != 0)
fakeRoot.left = hashMap.get(arr[1]);
if(arr[2] != 0)
fakeRoot.right = hashMap.get(arr[2]);
}
root = hashMap.get(root.value);
getMaxBST(root);
System.out.println(max);
// System.out.println(bstNode.value);
// System.out.println(isBST(root));
}
}
#include<bits/stdc++.h>
using namespace std;
struct ReturnType{
int maxBSTHead;
int maxBSTSize;
int MIN;
int MAX;
ReturnType(int root,int size,int Min,int Max):maxBSTHead(root),maxBSTSize(si***(Min),MAX(Max){}
};
ReturnType process(int root,int* lc,int* rc)
{
// base case 注意最大最小值的赋值
if(!root) return ReturnType(0,0,INT_MAX,INT_MIN);
// 搜集到左右子树的信息
ReturnType ldata = process(lc[root],lc,rc);
ReturnType rdata = process(rc[root],lc,rc);
// 整合
// 以当前结点为根的最大值与最小值
int max_ = max(root,max(ldata.MAX,rdata.MAX));
int min_ = min(root,min(ldata.MIN,rdata.MIN));
// 最大搜索二叉子树来源于左子树或右子树
int curMaxBSTHead = ldata.maxBSTSize>rdata.maxBSTSize ? ldata.maxBSTHead:rdata.maxBSTHead;
int curMaxBSTSize = max(ldata.maxBSTSize,rdata.maxBSTSize);
// 要把根节点加入进去的情况
if(ldata.maxBSTHead == lc[root] && rdata.maxBSTHead == rc[root] && root>ldata.MAX && root<rdata.MIN)
{
curMaxBSTHead = root;
curMaxBSTSize = 1 + ldata.maxBSTSize + rdata.maxBSTSize;
}
return ReturnType(curMaxBSTHead,curMaxBSTSi***_,max_);
}
int main()
{
int n,root;
cin>>n>>root;
int* lc = new int[n+1];
int* rc = new int[n+1];
int p;
for(int i=0;i<n;++i)
{
cin>>p;
cin>>lc[p]>>rc[p];
}
int ans = process(root,lc,rc).maxBSTSize;
cout<<ans<<endl;
return 0;
}
import java.lang.Math;
import java.util.Scanner;
import java.util.HashMap;
class Info{
boolean flag = true;
int nodesNum = 0;
}
class Node{
int value;
Node left;
Node right;
public Node(int value){
this.value = value;
}
}
public class Main{
public static void main(String[] args){
HashMap<Integer, Node> map = new HashMap<>();
Scanner sc = new Scanner(System.in);
String firstLine = sc.nextLine();
String[] params = firstLine.split(" ");
int n = Integer.valueOf(params[0]);
int rootVal = Integer.valueOf(params[1]);
Node root = new Node(rootVal);
map.put(rootVal, root);
//构建二叉树
for(int i=0; i<n; i++){
String line = sc.nextLine();
String[] str = line.split(" ");
int faVal = Integer.valueOf(str[0]);
int lchVal = Integer.valueOf(str[1]);
int rchVal = Integer.valueOf(str[2]);
Node curNode = map.get(faVal);
if(lchVal != 0){
curNode.left = new Node(lchVal);
map.put(lchVal, curNode.left);
}
if(rchVal != 0){
curNode.right = new Node(rchVal);
map.put(rchVal, curNode.right);
}
}
Info info = process(root);
System.out.println(info.nodesNum);
}
public static Info process(Node node){
Info curInfo = new Info();
if(node == null){
return curInfo;
}
Info leftInfo = process(node.left);
Info rightInfo = process(node.right);
if(((leftInfo.flag && rightInfo.flag) != true) ||
(node.left != null && getTreeMaxValue(node.left)>node.value) ||
(node.right != null && getTreeMinValue(node.right)<node.value)){
curInfo.flag = false;
curInfo.nodesNum = Math.max(leftInfo.nodesNum, rightInfo.nodesNum);
return curInfo;
}
curInfo.nodesNum = leftInfo.nodesNum + rightInfo.nodesNum + 1;
return curInfo;
}
public static int getTreeMaxValue(Node node){
while(node.right != null){
node = node.right;
}
return node.value;
}
public static int getTreeMinValue(Node node){
while(node.left != null){
node = node.left;
}
return node.value;
}
} import java.lang.Math;
import java.util.Scanner;
import java.util.HashMap;
class Info{
boolean flag = true;
int nodesNum = 0;
int max;
int min;
}
class Node{
int value;
Node left;
Node right;
public Node(int value){
this.value = value;
}
}
public class Main{
public static void main(String[] args){
HashMap<Integer, Node> map = new HashMap<>();
Scanner sc = new Scanner(System.in);
String firstLine = sc.nextLine();
String[] params = firstLine.split(" ");
int n = Integer.valueOf(params[0]);
int rootVal = Integer.valueOf(params[1]);
Node root = new Node(rootVal);
map.put(rootVal, root);
//构建二叉树
for(int i=0; i<n; i++){
String line = sc.nextLine();
String[] str = line.split(" ");
int faVal = Integer.valueOf(str[0]);
int lchVal = Integer.valueOf(str[1]);
int rchVal = Integer.valueOf(str[2]);
Node curNode = map.get(faVal);
if(lchVal != 0){
curNode.left = new Node(lchVal);
map.put(lchVal, curNode.left);
}
if(rchVal != 0){
curNode.right = new Node(rchVal);
map.put(rchVal, curNode.right);
}
}
Info info = process(root);
System.out.println(info.nodesNum);
}
public static Info process(Node node){
Info curInfo = new Info();
if(node == null){
return curInfo;
}
Info leftInfo = process(node.left);
Info rightInfo = process(node.right);
curInfo.max = node.right==null ? node.value : rightInfo.max;
curInfo.min = node.left==null ? node.value : leftInfo.min;
if(((leftInfo.flag && rightInfo.flag) != true) ||
(node.left != null && leftInfo.max>node.value) ||
(node.right != null && rightInfo.min<node.value)){
curInfo.flag = false;
curInfo.nodesNum = Math.max(leftInfo.nodesNum, rightInfo.nodesNum);
return curInfo;
}
curInfo.nodesNum = leftInfo.nodesNum + rightInfo.nodesNum + 1;
return curInfo;
}
} #include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
class TreeNode{
public:
int val;
TreeNode* left, * right;
TreeNode(int val = 0, TreeNode* left = nullptr, TreeNode* right = nullptr):
val(val), left(left), right(right){}
};
class Solution{
public:
static bool checkRoot(TreeNode* root, TreeNode* left, TreeNode* right){
while(right != nullptr && right->left != nullptr) right = right->left;
while(left != nullptr && left->right != nullptr) left = left->right;
if((left == nullptr || left->val < root->val) &&
(right == nullptr || right->val > root->val)){
return true;
}
return false;
}
static pair<int, TreeNode*> getMaxBSTree(TreeNode* root){
if(root == nullptr) return make_pair(0, nullptr);
int rootResSize = 0;
pair<int, TreeNode*> rootRes;
pair<int, TreeNode*> leftRes = getMaxBSTree(root->left);
pair<int, TreeNode*> rightRes = getMaxBSTree(root->right);
if (leftRes.second == root->left && rightRes.second == root->right
&& checkRoot(root, root->left, root->right)){
rootResSize = leftRes.first + rightRes.first + 1;
rootRes.first = rootResSize;
rootRes.second = root;
}else{
rootRes = leftRes.first > rightRes.first ? leftRes : rightRes;
}
return rootRes;
}
};
int main(){
int n, rootVal;
int line[3];
TreeNode* root = nullptr;
unordered_map<int, TreeNode*> treeNodes;
treeNodes.insert(make_pair(0, nullptr));
cin >> n >> rootVal;
while(n--){
cin >> line[0] >> line[1] >> line[2];
for(int i = 0; i < 3; i++){
if(treeNodes.count(line[i]) == 0){
treeNodes.insert(make_pair(line[i], new TreeNode(line[i])));
}
}
treeNodes[line[0]]->left = treeNodes[line[1]];
treeNodes[line[0]]->right = treeNodes[line[2]];
}
root = treeNodes[rootVal];
cout << Solution::getMaxBSTree(root).first;
return 0;
} import java.util.*;
class Node {
public int val;
public Node right;
public Node left;
public Node (int val) {
this.val = val;
}
}
class ReturnType {
public Node maxBSTHead;
public int maxBSTSize;
public int max;
public int min;
public ReturnType(Node maxBSTHead, int maxBSTSize, int min, int max) {
this.maxBSTHead = maxBSTHead;
this.maxBSTSize = maxBSTSize;
this.min = min;
this.max = max;
}
}
public class Main {
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Node head = constructTree(sc, n);
int result = returnSize(head);
System.out.println(result);
}
public static Node constructTree (Scanner sc, int n) {
HashMap<Integer, Node> map = new HashMap<>();
int rootVal = sc.nextInt();
Node root = new Node(rootVal);
map.put(rootVal, root);
for (int i = 0; i < n; i++) {
int nodeVal = sc.nextInt();
int leftVal = sc.nextInt();
int rightVal = sc.nextInt();
if (map.containsKey(nodeVal)) {
Node tmpNode = map.get(nodeVal);
Node leftNode = leftVal == 0 ? null : new Node(leftVal);
Node rightNode = rightVal == 0 ? null : new Node(rightVal);
tmpNode.left = leftNode;
tmpNode.right = rightNode;
if (leftVal != 0)
map.put(leftVal, leftNode);
if (rightVal != 0)
map.put(rightVal, rightNode);
}
}
return root;
}
public static int returnSize (Node head) {
return process(head).maxBSTSize;
}
public static ReturnType process (Node x) {
//base case:最小值是系统最大,最大值是系统最小
if (x == null)
return new ReturnType(null, 0, Integer.MAX_VALUE, Integer.MIN_VALUE);
//默认直接得到左右树全部信息
ReturnType leftData = process(x.left);
ReturnType rightData = process(x.right);
//信息整合:
/*
同时对以x为头的子树也做同样要求,也需要返回如ReturnType描述的全部信息
*/
int min = Math.min(x.val, Math.min(leftData.min, rightData.min));
int max = Math.max(x.val, Math.max(leftData.max, rightData.max));
int maxBSTSize = Math.max(leftData.maxBSTSize, rightData.maxBSTSize);
Node maxBSTHead = leftData.maxBSTSize >= rightData.maxBSTSize ? leftData.maxBSTHead: rightData.maxBSTHead;
if (leftData.maxBSTHead == x.left && rightData.maxBSTHead == x.right && x.val > leftData.max && x.val < rightData.min) {
maxBSTSize = leftData.maxBSTSize + rightData.maxBSTSize + 1;
maxBSTHead = x;
}
return new ReturnType(maxBSTHead, maxBSTSize, min, max);
}
} //参考左神
import java.util.*;
public class Main{
static class Node{
int key;
Node left;
Node right;
Node(int k){key = k;}
}
static Map<Integer, Node> map = new HashMap<>();
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
//0->size; 1->min; 2->max
int[] record = new int[3];
int n = sc.nextInt(), rootVal = sc.nextInt();
Node root = new Node(rootVal);
map.put(rootVal, root);
while(sc.hasNext()){
int father = sc.nextInt();
int leftV = sc.nextInt(), rightV = sc.nextInt();
Node left = leftV == 0 ? null : new Node(leftV);
if(left != null) map.put(left.key, left);
Node right = rightV == 0 ? null : new Node(rightV);
if(right != null)map.put(right.key, right);
Node f = map.get(father);
f.left = left;
f.right = right;
}
posOrder(root, record);
System.out.print(record[0]);
}
static Node posOrder(Node head, int[]record){
if(head == null){
record[0] = 0;
record[1] = Integer.MAX_VALUE;
record[2] = Integer.MIN_VALUE;
return null;
}
int val = head.key;
Node lBst = posOrder(head.left, record);
int lSize = record[0], lMin = record[1], lMax = record[2];
Node rBst = posOrder(head.right, record);
int rSize = record[0], rMin = record[1], rMax = record[2];
record[1] = Math.min(lMin, val);
record[2] = Math.max(rMax, val);
if(lBst == head.left && rBst == head.right && val > lMax && val < rMin){
record[0] = lSize + rSize + 1;
return head;
}
record[0] = Math.max(lSize, rSize);
return lSize > rSize ? lBst : rBst;
}
}
#include <bits/stdc++.h>
#define maxn 1000001
using namespace std;
struct Node{
int val;
Node* left;
Node* right;
};
Node nodes[maxn];
struct Data{
int min;
int max;
int size;
Node* head;
Data(int mi, int ma, int nod, Node* hea){
min = mi;
max = ma;
size = nod;
head = hea;
}
};
Data process(Node* root){
if(root == NULL){
return Data(INT_MAX, INT_MIN, 0, root);
}
Data leftNode = process(root->left);
Data rightNode = process(root->right);
int together = 0;
if(leftNode.head == root->left
&& rightNode.head == root->right
&& leftNode.max < root->val
&& rightNode.min > root->val
) {
together = leftNode.size + rightNode.size + 1;
}
int maxSize = max(max(leftNode.size, rightNode.size), together);
Node* maxHead = leftNode.size > rightNode.size ? leftNode.head : rightNode.head;
if(maxSize == together) {
maxHead = root;
}
return Data(min(min(leftNode.min,rightNode.min),root->val),
max(max(leftNode.max,rightNode.max),root->val),
maxSize,
maxHead);
}
int main()
{
int n,r;
scanf("%d%d",&n,&r);
for(int i=0;i<n;i++){
int index,left,right;
scanf("%d%d%d",&index,&left,&right);
nodes[index].val = index;
if(left)
nodes[index].left = &nodes[left];
else
nodes[index].left = NULL;
if(right)
nodes[index].right = &nodes[right];
else
nodes[index].right = NULL;
}
int res = process(&nodes[r]).size;
printf("%d\n",res);
return 0;
}