1.题目描述
给定一棵二叉树的头节点head,已知其中所有节点的值都不一样,找到含有节点最多的搜索二叉子树,并返回这棵子树的头节点。例如,下图中,右树就是左树的最大搜索子树。
2.解题思路
首先解释一下什么是最大搜索子树,就是二叉搜索树,任意节点的值必定大于左子树的最大值,小于右子树的最小值,且左右子树都是二叉搜索树。
所以很容易想到使用递归来进行解题。
1.整个过程使用后序遍历
2.遍历到当前节点记为cur时,先遍历cur的左子树收集4个信息,分别是左子树上最大搜索二叉子树的头节点(lBST)、节点数(lSize)、最小值(lMin)和最大值(lMax)。再遍历cur的右子树收集4个信息,分别是右子树上最大搜索二叉子树的头节点(rBST)、节点数(rSize)、最小值(rMin)和最大值(rMax)
3.根据步骤2所收集的信息,判断是否满足搜索子树的定义(1,要保证返回的节点lBST和递归时的节点left是一个,rBST也是如此,并且当前节点的值满足大于左子树的最大值,小于右子树的最小值),如果满足就返回cur节点,如果不满足就返回lBST和rBST中子节点数多的那一个
参考:https://www.cnblogs.com/yangtong/p/6687078.html
参考:https://blog.csdn.net/gaoyueace/article/details/90404985
3.代码实现
# Definition for a binary tree node.
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
def main(self):
root = self.buidTree()
res = self.posOrder(root,[0,0,0])
print res.val
def buidTree(self):
root = TreeNode(6)
root.left = TreeNode(1)
root.right = TreeNode(12)
root.left.left = TreeNode(0)
root.left.right = TreeNode(3)
root.right.left = TreeNode(10)
root.right.left.left = TreeNode(4)
root.right.left.left.left = TreeNode(2)
root.right.left.left.right = TreeNode(5)
root.right.left.right = TreeNode(14)
root.right.left.right.left = TreeNode(11)
root.right.left.right.right = TreeNode(15)
root.right.right = TreeNode(13)
root.right.right.left = TreeNode(20)
root.right.right.right = TreeNode(16)
return root
def posOrder(self, root, record):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
record[0] = 0
record[1] = float("inf")
record[2] = float("-inf")
return None
value = root.val
left = root.left
right = root.right
lBST = self.posOrder(root.left,record)
lSize = record[0]
lMin = record[1]
lMax = record[2]
rBST = self.posOrder(root.right, record)
rSize = record[0]
rMin = record[1]
rMax = record[2]
# 保存当前子树中的最大值与最小值,不是只保存左子树的最大值与右子树的最小值
record[1] = min(lMin,value)
record[2] = max(rMax,value)
# 只有当左右两个子树的根节点是当前节点的左右子节点,当前节点才能作为根节点加入
if (not left and not lBST and not right and not rBST) or (left.val == lBST.val and right.val == rBST.val) and lMax < value and value < rMin:
record[0] = lSize + rSize + 1
return root
# 若左右子树不能合并,返回当前最长的那个子树的根节点
else:
record[0] = max(lSize,rSize)
if lSize > rSize:
return lBST
else:
return rBST
s=Solution()
s.main()