-
題目
給定一個二叉樹的頭節點head,已知其中所有節點的值都不一樣,找到含有節點最多的搜索二叉子樹,並返回這個子樹的頭節點。
例如,
![]()
最大搜索子樹如右圖
-
解析
首先解釋一下什么是最大搜索子樹,就是二叉搜索樹,任意節點的值必定大於左子樹的最大值,小於右子樹的最小值,且左右子樹都是二叉搜索樹。
所以很容易想到使用遞歸來進行解題。
1.整個過程使用后序遍歷
2.遍歷到當前節點記為cur時,先遍歷cur的左子樹收集4個信息,分別是左子樹上最大搜索二叉子樹的頭節點(lBST)、節點數(lSize)、最小值(lMin)和最大值(lMax)。再遍歷cur的右子樹收集4個信息,分別是右子樹上最大搜索二叉子樹的頭節點(rBST)、節點數(rSize)、最小值(rMin)和最大值(rMax)
3.根據步驟2所收集的信息,判斷是否滿足搜索子樹的定義,如果滿足就返回cur節點,如果不滿足就返回lBST和rBST中節點數多的那一個
-
代碼
1 public Node biggestSubBST(Node head) { 2 int[] record = new int[3]; 3 return posOrder(head, record); 4 } 5 6 public Node posOrder(Node head, int[] record) { 7 if (head == null) { 8 record[0] = 0; 9 record[1] = Integer.MAX_VALUE; 10 record[2] = Integer.MIN_VALUE; 11 return null; 12 } 13 int value = head.value; 14 Node left = head.left; 15 Node right = head.right; 16 Node lBST = posOrder(left, record); 17 int lSize = record[0]; 18 int lMin = record[1]; 19 int lMax = record[2]; 20 Node rBST = posOrder(right, record); 21 int rSize = record[0]; 22 int rMin = record[1]; 23 int rMax = record[2]; 24 25 record[1] = Math.min(lMin, value); 26 record[2] = Math.max(rMax, value); 27 28 if (left == lBST && right == rBST && lMax < value && value < rMin) { 29 record[0] = lSize + rSize + 1; 30 return head; 31 } 32 33 record[0] = Math.max(lSize, rSize); 34 return lSize > rSize ? lBST : rBST; 35 }
-
參考資料
《程序員代碼面試指南》 左程雲

