一天一道算法题(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 }
-
参考资料
《程序员代码面试指南》 左程云