最大搜索子樹

給定一個二叉樹的頭結點,返回最大搜索子樹的大小。

?

我們先定義結點:

    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.pswp.cn/news/445499.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445499.shtml
英文地址,請注明出處:http://en.pswp.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;數據的特征提取特征生成特征選擇第六步…