题目:
给定一棵二叉树的头节点head,已知其中所有节点的值都不一样,找到含有节点最多的搜索二叉树,并返回这棵子树的头节点。(注意子树的概念)
基本思路:
以节点node为头的树中,最大的搜索二叉树只可能来自以下的两种情况:
- node的左子树和右子树都是搜索二叉树,并且左子树的最大值小于node,右子树的最小值大于node,此时,以node为头的整棵树都是搜索二叉树。
- 如果不满足情况1,那么最大的搜索二叉树来自node左子树的最大搜索二叉子树或者node右子树的最大搜索二叉子树
整体过程是二叉树的后序遍历,过程如下:
- 遍历到当前节点cur时,先遍历左子树收集四个信息,分别是左子树上最大搜索二叉树的头节点(lBST),节点数(lSize),最大值(lMax)和最小值(lMin)。再遍历右子树,也收集四个信息rBST, rSize, rMax, rMin。
- 根据步骤一收集的信息,判断是否满足情况1,如果满足,返回cur。如果不满足,返回lBST, rBST中最大的一个。
def biggestSubBST(root):
def findBiggestSubBST(root, record):
if not root:
record[0] = 0
record[1] = sys.maxsize
record[2] = -sys.maxsize
return None
leftBST = findBiggestSubBST(root.left, record)
leftSize = record[0]
leftMin = record[1]
leftMax = record[2]
rightBST = findBiggestSubBST(root.right, record)
rightSize = record[0]
rightMin = record[1]
rightMax = record[2]
record[1] = min(leftMin, int(root.val))
record[2] = max(rightMax, int(root.val))
if leftBST == root.left and rightBST == root.right and \
rightMin > int(root.val) and leftMax < int(root.val):
record[0] = leftSize + rightSize + 1
return root
record[0] = max(leftSize, rightSize)
if leftSize > rightSize:
return leftBST
else:
return rightBST
if not root:
return
record = [0 for i in range(3)]
return findBiggestSubBST(root, record)