一天一道算法题(6)---找到二叉树中最大的搜索二叉子树

  • 题目

给定一个二叉树的头节点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     }
  •  参考资料

《程序员代码面试指南》  左程云

posted @ 2017-04-10 22:02  杨同不爱吃洋葱  阅读(2002)  评论(0编辑  收藏  举报