IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 二叉树的递归套路——最大二叉搜索子树头结点 -> 正文阅读

[数据结构与算法]二叉树的递归套路——最大二叉搜索子树头结点

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

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

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

第二种可能性:与X有关(以X为头节点),则需要:
左树整体是搜索二叉树
&&
右树整体是搜索二叉树
&&
左树上的最大值<头节点
&&
右树上的最小值>头节点

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

  1. 整颗子树上最大二叉搜索子树的头节点
  2. 整颗子树上最大二叉搜索子树的大小(为什么需要大小,因为需要通过比较大小返回大的那一个)
  3. 整颗子树整体是否为搜索二叉树(但是此条信息可以通过第一条信息得出,如果在一棵子树上,最大二叉搜索子树的头节点就是子树的头节点,意味着整颗子树就是搜索二叉树
  4. 整颗子树上的最大值
  5. 整颗子树上的最小值

所以不用额外设置一个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!");
	}
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-16 17:56:08  更:2021-12-16 17:56:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/30 20:08:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码