二叉树的递归套路——最大二叉搜索子树头结点

简介: 二叉树的递归套路——最大二叉搜索子树头结点

给定一颗二叉树的头结点head,返回这颗二叉树中最大的二叉搜索子树的头结点

此题跟这篇文章解题思路类似——二叉树的递归套路——最大二叉搜索子树大小

第一种可能性:与X无关,就是说以X为头结点的左树上有一颗子树是最大搜索二叉树;或者以X为头结点的右树上有一颗子树是最大搜索二叉树。 两边谁大就返回那边子树的头结点。

第二种可能性:与X有关(以X为头节点),则需要:

左树整体是搜索二叉树

&&

右树整体是搜索二叉树

&&

左树上的最大值<头节点

&&

右树上的最小值>头节点

所以每颗子树需要返回的信息就是:

   整颗子树上最大二叉搜索子树的头节点

   整颗子树上最大二叉搜索子树的大小(为什么需要大小,因为需要通过比较大小返回大的那一个)

   整颗子树整体是否为搜索二叉树(但是此条信息可以通过第一条信息得出,如果在一棵子树上,最大二叉搜索子树的头节点就是子树的头节点,意味着整颗子树就是搜索二叉树)

   整颗子树上的最大值

   整颗子树上的最小值

所以不用额外设置一个boolean类型变量来标记整颗子树是否为搜索二叉树

public static class Info{
    public Node maxSubBSTHead;
    //public boolean isAllBST;
    public int maxSubBSTSize;
    public int max;
    public int min;
    public Info(Node h,int size,int ma,int mi) {
      maxSubBSTHead=h;
      maxSubBSTSize=size;
      max=ma;
      min=mi;
    }
  }

完整代码:

package com.harrison.class08;
import java.util.ArrayList;
public class Code07_MaxSubBSTHead {
  public static class Node {
    public int value;
    public Node left;
    public Node right;
    public Node(int data) {
      this.value = data;
    }
  }
  public static class Info{
    public Node maxSubBSTHead;
    public int maxSubBSTSize;
    public int max;
    public int min;
    public Info(Node h,int size,int ma,int mi) {
      maxSubBSTHead=h;
      maxSubBSTSize=size;
      max=ma;
      min=mi;
    }
  }
  public static Info process1(Node head) {
    if(head==null) {
      return null;
    }
    Info leftInfo=process1(head.left);
    Info rightInfo=process1(head.right);
    Node maxSubBSTHead=null;
    int maxSubBSTSize=0;
    int max=head.value;
    int min=head.value;
    if(leftInfo!=null) {
      max=Math.max(max, leftInfo.max);
      min=Math.min(min, leftInfo.min);
      maxSubBSTHead=leftInfo.maxSubBSTHead;
      maxSubBSTSize=leftInfo.maxSubBSTSize;
    }
    if(rightInfo!=null) {
      max=Math.max(max, rightInfo.max);
      min=Math.min(min, rightInfo.min);
      if(rightInfo.maxSubBSTSize>maxSubBSTSize) {
        maxSubBSTSize=rightInfo.maxSubBSTSize;
        maxSubBSTHead=rightInfo.maxSubBSTHead;
      }
    }
    // 如果在一棵子树上,最大二叉搜索子树的头节点就是子树的头节点,意味着整颗子树就是搜索二叉树
    if(
      (leftInfo==null?true:(leftInfo.maxSubBSTHead==head.left))
      &&
      (rightInfo==null?true:(rightInfo.maxSubBSTHead==head.right))
      &&
      (leftInfo==null?true:leftInfo.max<head.value)
      &&
      (rightInfo==null?true:rightInfo.min>head.value)
      ) {
      maxSubBSTHead=head;
      maxSubBSTSize=(
              (leftInfo==null?0:leftInfo.maxSubBSTSize)
              +
              (rightInfo==null?0:rightInfo.maxSubBSTSize)
              +1
                );
    }
    return new Info(maxSubBSTHead, maxSubBSTSize, max, min);
  }
  public static Node maxSubBSTHead1(Node head) {
    if(head==null) {
      return null;
    }
    return process1(head).maxSubBSTHead;
  }
  public static int getBSTSize(Node head) {
    if (head == null) {
      return 0;
    }
    ArrayList<Node> arr = new ArrayList<>();
    in(head, arr);
    for (int i = 1; i < arr.size(); i++) {
      if (arr.get(i).value <= arr.get(i - 1).value) {
        return 0;
      }
    }
    return arr.size();
  }
  public static void in(Node head, ArrayList<Node> arr) {
    if (head == null) {
      return;
    }
    in(head.left, arr);
    arr.add(head);
    in(head.right, arr);
  }
  public static Node maxSubBSTHead2(Node head) {
    if (head == null) {
      return null;
    }
    if (getBSTSize(head) != 0) {
      return head;
    }
    Node leftAns = maxSubBSTHead1(head.left);
    Node rightAns = maxSubBSTHead1(head.right);
    return getBSTSize(leftAns) >= getBSTSize(rightAns) ? leftAns : rightAns;
  }
  public static Node generateRandomBST(int maxLevel, int maxValue) {
    return generate(1, maxLevel, maxValue);
  }
  public static Node generate(int level, int maxLevel, int maxValue) {
    if (level > maxLevel || Math.random() < 0.5) {
      return null;
    }
    Node head = new Node((int) (Math.random() * maxValue));
    head.left = generate(level + 1, maxLevel, maxValue);
    head.right = generate(level + 1, maxLevel, maxValue);
    return head;
  }
  public static void main(String[] args) {
    int maxLevel = 4;
    int maxValue = 100;
    int testTimes = 1000000;
    for (int i = 0; i < testTimes; i++) {
      Node head = generateRandomBST(maxLevel, maxValue);
      if (maxSubBSTHead1(head) != maxSubBSTHead2(head)) {
        System.out.println("Oops!");
      }
    }
    System.out.println("finish!");
  }
}
相关文章
|
5月前
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
54 0
|
算法 C语言 C++
【树】你真的会二叉树了嘛? --二叉树LeetCode专题
先来一题简单的题目练练手,之前有提到过,二叉树的前序遍历就是通过根左右的遍历方式来进行的,所以这题总体思路也是一样.不过要说明的是,这里采用了c语言,所以输出时需要自己创建一个动态数组,每次将访问到的val存入动态数组当中即可.
86 0
|
10月前
|
存储 算法 测试技术
【深度优先】LeetCode1932:合并多棵二叉搜索树
【深度优先】LeetCode1932:合并多棵二叉搜索树
LeetCode刷题Day14——二叉树(完全二叉树、平衡二叉树、二叉树路径、左叶子之和)
一、完全二叉树的节点个数 题目链接:222. 完全二叉树的节点个数
【Leetcode -965.单值二叉树 -572.另一颗树的子树】
【Leetcode -965.单值二叉树 -572.另一颗树的子树】
48 0
|
算法 C语言 C++
【树】你真的会二叉树了嘛? --二叉树LeetCode专题Ⅳ
本章依然是二叉树的刷题 忘记的朋友们可以去看看我的二叉树专题
91 0
Leedcode二叉搜索树中的搜索[层序遍历+利用性质]
Leedcode二叉搜索树中的搜索[层序遍历+利用性质]
98 0
Leedcode二叉搜索树中的搜索[层序遍历+利用性质]
leetcode572 另一颗树的子树
leetcode572 另一颗树的子树
73 0
leetcode572 另一颗树的子树
|
数据采集 算法
数据结构与算法—二叉树的层序、前序中序后序(递归、非递归)遍历
层序遍历。听名字也知道是按层遍历。我们知道一个节点有左右节点。而每一层一层的遍历都和左右节点有着很大的关系。也就是我们选用的数据结构不能一股脑的往一个方向钻,而左右应该均衡考虑。这样我们就选用队列来实现。
228 0
数据结构与算法—二叉树的层序、前序中序后序(递归、非递归)遍历
|
算法 API
数据结构与算法—二叉排序(查找)树
前面介绍学习的大多是线性表相关的内容,把指针搞懂后其实也没有什么难度。规则相对是简单的。
86 0
数据结构与算法—二叉排序(查找)树

热门文章

最新文章