最大搜索子树

给定一个二叉树的头结点,返回最大搜索子树的大小。

 

我们先定义结点:

    public static class Node {public int value;public Node left;public Node right;public Node(int data) {this.value = data;}}

分析:

直接判断每个节点左边小右边大是不对滴

 

可以暴力判断所有的子树,就不说了。

 

最大搜索子树可能性:

第一种可能性,以node为头的结点的最大二叉搜索子树可能来自它左子树;
第二种可能性,以node为头的结点的最大二叉搜索子树可能来自它右子树;
第三种可能性,左树整体是搜索二叉树,右树整体也是搜索二叉树,而且左树的头是node.left,右树的头是node.right,且左树的最大值< node.value,右树的最小值 > node.value, 那么以我为头的整棵树都是搜索二叉树;
 

第三种可能性的判断,需要的信息有:左子树的最大值、右子树的最小值、左子树是不是搜索二叉树、右子树是不是搜索二叉树

还有左右搜索二叉树的最大深度。

我们判断了自己,并不知道自己是哪边的子树,我们要返回自己的最大值和最小值。

这样,定义一个返回类型:

    public static class ReturnType{public int size;//最大搜索子树深度public Node head;//最大搜索子树的根public int min;//子树最小public int max;//子树最大public ReturnType(int a, Node b,int c,int d) {this.size =a;this.head = b;this.min = c;this.max = d;}}

然后开始写代码:

注意:

1)NULL返回深度0,头为NULL,最大值最小值返回系统最大和最小,这样才不会影响别的判断。

	public static ReturnType process(Node head) {if(head == null) {return new ReturnType(0,null,Integer.MAX_VALUE, Integer.MIN_VALUE);}Node left = head.left;//取信息ReturnType leftSubTressInfo = process(left);Node right = head.right;ReturnType rightSubTressInfo = process(right);int includeItSelf = 0;if(leftSubTressInfo.head == left //            左子树为搜索树&&rightSubTressInfo.head == right//    右子树为搜索树&& head.value > leftSubTressInfo.max// 左子树最大值小于当前节点&& head.value < rightSubTressInfo.min//右子树最小值大于当前节点) {includeItSelf = leftSubTressInfo.size + 1 + rightSubTressInfo.size;//当前节点为根的二叉树为搜索树}int p1 = leftSubTressInfo.size;int p2 = rightSubTressInfo.size;int maxSize = Math.max(Math.max(p1, p2), includeItSelf);//最大搜索树深度Node maxHead = p1 > p2 ? leftSubTressInfo.head : rightSubTressInfo.head;if(maxSize == includeItSelf) {maxHead = head;}//最大搜索树的根:来自左子树、来自右子树、本身return new ReturnType(maxSize,                                                                     //深度maxHead,                                                                     //根Math.min(Math.min(leftSubTressInfo.min,rightSubTressInfo.min),head.value),    //最小Math.max(Math.max(leftSubTressInfo.max,rightSubTressInfo.max),head.value));	//最大}

可以进一步改进:

空间浪费比较严重

其实返回值为三个int,一个node,我们可以把三个int合起来,用全局数组记录,函数只返回node(搜索树的根)即可。

给出完整代码:

public class BiggestSubBSTInTree {public static class Node {public int value;public Node left;public Node right;public Node(int data) {this.value = data;}}public static Node biggestSubBST(Node head) {int[] record = new int[3]; // 0->size, 1->min, 2->maxreturn posOrder(head, record);}public static class ReturnType{public int size;//最大搜索子树深度public Node head;//最大搜索子树的根public int min;//子树最小public int max;//子树最大public ReturnType(int a, Node b,int c,int d) {this.size =a;this.head = b;this.min = c;this.max = d;}}public static ReturnType process(Node head) {if(head == null) {return new ReturnType(0,null,Integer.MAX_VALUE, Integer.MIN_VALUE);}Node left = head.left;//取信息ReturnType leftSubTressInfo = process(left);Node right = head.right;ReturnType rightSubTressInfo = process(right);int includeItSelf = 0;if(leftSubTressInfo.head == left //            左子树为搜索树&&rightSubTressInfo.head == right//    右子树为搜索树&& head.value > leftSubTressInfo.max// 左子树最大值小于当前节点&& head.value < rightSubTressInfo.min//右子树最小值大于当前节点) {includeItSelf = leftSubTressInfo.size + 1 + rightSubTressInfo.size;//当前节点为根的二叉树为搜索树}int p1 = leftSubTressInfo.size;int p2 = rightSubTressInfo.size;int maxSize = Math.max(Math.max(p1, p2), includeItSelf);//最大搜索树深度Node maxHead = p1 > p2 ? leftSubTressInfo.head : rightSubTressInfo.head;if(maxSize == includeItSelf) {maxHead = head;}//最大搜索树的根:来自左子树、来自右子树、本身return new ReturnType(maxSize,                                                                     //深度maxHead,                                                                     //根Math.min(Math.min(leftSubTressInfo.min,rightSubTressInfo.min),head.value),   //最小Math.max(Math.max(leftSubTressInfo.max,rightSubTressInfo.max),head.value));	 //最大}public 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 value = head.value;Node left = head.left;Node right = head.right;Node lBST = posOrder(left, record);int lSize = record[0];int lMin = record[1];int lMax = record[2];Node rBST = posOrder(right, record);int rSize = record[0];int rMin = record[1];int rMax = record[2];record[1] = Math.min(rMin, Math.min(lMin, value)); // lmin, value, rmin -> min record[2] = Math.max(lMax, Math.max(rMax, value)); // lmax, value, rmax -> maxif (left == lBST && right == rBST && lMax < value && value < rMin) {record[0] = lSize + rSize + 1;//修改深度return head;                  //返回根}//满足当前构成搜索树的条件record[0] = Math.max(lSize, rSize);//较大深度return lSize > rSize ? lBST : rBST;//返回较大搜索树的根}// for test -- print treepublic static void printTree(Node head) {System.out.println("Binary Tree:");printInOrder(head, 0, "H", 17);System.out.println();}public static void printInOrder(Node head, int height, String to, int len) {if (head == null) {return;}printInOrder(head.right, height + 1, "v", len);String val = to + head.value + to;int lenM = val.length();int lenL = (len - lenM) / 2;int lenR = len - lenM - lenL;val = getSpace(lenL) + val + getSpace(lenR);System.out.println(getSpace(height * len) + val);printInOrder(head.left, height + 1, "^", len);}public static String getSpace(int num) {String space = " ";StringBuffer buf = new StringBuffer("");for (int i = 0; i < num; i++) {buf.append(space);}return buf.toString();}public static void main(String[] args) {Node head = new Node(6);head.left = new Node(1);head.left.left = new Node(0);head.left.right = new Node(3);head.right = new Node(12);head.right.left = new Node(10);head.right.left.left = new Node(4);head.right.left.left.left = new Node(2);head.right.left.left.right = new Node(5);head.right.left.right = new Node(14);head.right.left.right.left = new Node(11);head.right.left.right.right = new Node(15);head.right.right = new Node(13);head.right.right.left = new Node(20);head.right.right.right = new Node(16);printTree(head);Node bst = biggestSubBST(head);printTree(bst);}}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/445499.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二叉树最长路径

分析&#xff1a; 暴力求每一段距离也可。 对于以本节点为根的二叉树&#xff0c;最远距离有三种可能&#xff1a; 1&#xff09;最远路径来自左子树 2 &#xff09;最远路径来自右子树&#xff08;图示与左子树同理&#xff09; 3&#xff09;最远路径为左右子树距离根最远…

判断完全二叉树

完全二叉树的定义: 一棵二叉树&#xff0c;除了最后一层之外都是完全填充的&#xff0c;并且最后一层的叶子结点都在左边。 https://baike.baidu.com/item/%E5%AE%8C%E5%85%A8%E4%BA%8C%E5%8F%89%E6%A0%91/7773232?fraladdin 百度定义 思路&#xff1a;层序遍历二叉树 如果…

判断二叉搜索树

二叉查找树&#xff08;Binary Search Tree&#xff09;&#xff0c;&#xff08;又&#xff1a;二叉搜索树&#xff0c;二叉排序树&#xff09;它或者是一棵空树&#xff0c;或者是具有下列性质的二叉树&#xff1a; 若它的左子树不空&#xff0c;则左子树上所有结点的值均小于…

剑指offer_01

文章目录[toc]第一章 面试流程1.1 面试官谈面试1.2 面试3种形式1.3 面试的3个环节第一章 面试流程 1.1 面试官谈面试 初级的程序员谈算法和数据结构&#xff0c;高级的程序员谈项目经验要对公司近况和项目情况了解不要紧张&#xff0c;不要马上上手写代码 1.2 面试3种形式 …

判断平衡二叉树

平衡二叉树&#xff08;Balanced Binary Tree&#xff09;具有以下性质&#xff1a;它是一棵空树或它的左右两个子树的高度差的绝对值不超过1。并且左右两个子树都是一棵平衡二叉树 &#xff08;不是我们平时意义上的必须为搜索树&#xff09; 判断一棵树是否为平衡二叉树&am…

剑指offer_02

文章目录第二章 面试需要的基础知识1.1 面试官谈基础知识1.2 编程语言1.3 数据结构1.4 算法和数据操作第二章 面试需要的基础知识 1.1 面试官谈基础知识 数据结构和算法&#xff0c;编程能力&#xff0c;部分数学能力&#xff0c;问题分析和推理能力编程基础&#xff0c;计算…

求完全二叉树的结点个数

第一次见这个题&#xff0c;看时间小于O(N)。。。。。 只能是二分啊。 但是怎么二分&#xff0c;条件是什么&#xff0c;真的想不到。 后来知道了&#xff0c;我们要找最深一层最右边那个结点。借此确定结点个数。 我们知道&#xff0c;满二叉树的结点个数和深度是有公式的&a…

剑指offer_03

文章目录第三章 高质量代码1.1 面试官谈高质量代码1.2 代码的规范性1.3 代码的完整性1.4 代码的鲁棒性第三章 高质量代码 1.1 面试官谈高质量代码 代码应该考虑异常状况和垃圾回收问题&#xff0c;不能忽视边界情况变量&#xff0c;函数命名应该要统一&#xff0c;备注要恰到…

剑指offer_04

文章目录第四章 解决面试题的思路1.1 面试官谈面试思路1.2 画图让问题抽象化1.3 举例让抽象问题具体化1.4 分解让复杂问题具体化第四章 解决面试题的思路 1.1 面试官谈面试思路 编程前讲自己的思路是一项考核指标&#xff0c;不能一开始就变成&#xff0c;面试的时候应该和面…

先序中序后序两两结合重建二叉树

遍历是对树的一种最基本的运算&#xff0c;所谓遍历二叉树&#xff0c;就是按一定的规则和顺序走遍二叉树的所有结点&#xff0c;使每一个结点都被访问一次&#xff0c;而且只被访问一次。由于二叉树是非线性结构&#xff0c;因此&#xff0c;树的遍历实质上是将二叉树的各个结…

剑指offer_05

文章目录第五章 优化时间和空间效率1.1 面试官谈效率1.2 时间效率1.3 时间效率和空间效率的平衡第五章 优化时间和空间效率 1.1 面试官谈效率 1.时间和空间复杂度是写程序的时候&#xff0c;我们需要分析的&#xff0c;最好每次写完代码后自己都可以将程序的时间和空间复杂度…

先序中序数组推后序数组

二叉树遍历 所谓遍历(Traversal)是指沿着某条搜索路线&#xff0c;依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问 题。 遍历是二叉树上最重要的运算之一&#xff0c;是二叉树上进行其它运算之基础。 从二叉树的递归定义可知&#xff0c;一…

剑指offer_06

文章目录第六章 面试中的各项能力1.1 面试官谈能力1.2 沟通能力和学习能力1.3 知识迁移能力1.4 抽象建模能力1.5 发散思维能力第六章 面试中的各项能力 1.1 面试官谈能力 1.礼貌平和&#xff0c;不卑不亢的和面试官沟通&#xff1b;逻辑清楚&#xff0c;详略得到的介绍项目经…

数据结构课上笔记11

满二叉树 (Full binary tree) 除最后一层无任何子节点外&#xff0c;每一层上的所有结点都有两个子结点二叉树。 国内教程定义&#xff1a;一个二叉树&#xff0c;如果每一个层的结点数都达到最大值&#xff0c;则这个二叉树就是满二叉树。也就是说&#xff0c;如果一个二叉树…

数据结构和算法(01)--- 算法复杂度

文章目录算法时间复杂度算法时间复杂度 要判断算法的好坏&#xff0c;可以从时间方面进行分析。算法运行的越快&#xff0c;所用的时间越短则算法越好。但是同一个算法在不同的平台上的运行时间不同。那么又该如何进行评判呢&#xff1f;我们采用时间复杂度进行衡量。 1.算法时…

数据结构课上笔记12

二叉树的存储结构 顺序存储结构 完全二叉树&#xff1a;用一组地址连续的 存储单元依次自上而下、自左至右存 储结点元素&#xff0c;即将编号为 i 的结点元 素存储在一维数组中下标为 i –1 的分量中。 一般二叉树&#xff1a;将其每个结点与完 全二叉树上的结点相对照&…

kaggle(01)-泰坦尼克号问题

经典又兼具备趣味性的Kaggle案例泰坦尼克号问题 大家都熟悉的『Jack and Rose』的故事&#xff0c;豪华游艇倒了&#xff0c;大家都惊恐逃生&#xff0c;可是救生艇的数量有限&#xff0c;无法人人都有&#xff0c;副船长发话了『lady and kid first&#xff01;』&#xff0c…

数据结构课上笔记13

树存储结构 父节点表示法 数据域&#xff1a;存放结点本身信息。 双亲域&#xff1a;指示本结点的双亲结点在数组中的位置。 对应的树&#xff1a; /* 树节点的定义 */ #define MAX_TREE_SIZE 100typedef struct{TElemType data;int parent; /* 父节点位置域 */ } PTNode;type…

数据结构课上笔记14

图是一种&#xff1a; 数据元素间存在多对多关系的数据结构 加上一组基本操作构成的抽象数据类型。 图 (Graph) 是一种复杂的非线性数据结构&#xff0c;由顶点集合及顶点间的关系&#xff08;也称弧或边&#xff09;集合组成。可以表示为&#xff1a; G&#xff1d;(V, V…

kaggle(03)-自行车租赁预测问题(基础版)

文章目录问题描述&#xff1a;问题解决分析问题&#xff1a;解决问题第一步&#xff1a;读取原始数据第二步&#xff1a;观察原始数据第三步&#xff1a;原始数据的可视化第四步&#xff1a;数据的预处理时间属性的分解第五步&#xff1a;数据的特征提取特征生成特征选择第六步…