题目:
有一棵二叉树,其中所有节点的值都不一样,找到含有节点最多 的搜索二叉子树,并返回这棵子树的头节点.
给定二叉树的头结点root,请返回所求的头结点,若出现多个节点最多的子树,返回头结点权值最大的。
测试用例:
输入:{4,2,6,1,5,3,#,#,#,#,#,#,#}
输出:{2,1,5}
思路:
一棵搜索二叉树要求任意结点满足左孩子值小于结点值小于右孩子值。可以采取递归的方式,先左后右遍历一棵树。遍历完左子树时,返回:左子树中最大二叉搜索树的结点;左子树中最大二叉搜索树的头结点;左子树中的最大值;左子树中的最小值。右子树亦如是。
有了这四个值,结合根节点,一共有两种情况:
1. 左右子树中,最大二叉搜索树头结点分别是当前结点的左右孩子,且左子树中最大值小于当前结点值,当前结点值小于右子树中的最小值。这说明以当前结点为根的子树也是一颗二叉搜索树。
2. 反之,以当前结点为根的子树不是二叉搜索树。此时,根据题意,返回结点数最多的一边,以及更新后的最大、最小值。如果结点数一致,返回值较大的一边。
代码:
class MaxSubtree:
def getMax(self, root):
# write code here
def dfs(root):
if not root:
return 0, None, -0x80000000, 0x7fffffff
left_num, left_node, left_max, left_min = dfs(root.left)
right_num, right_node, right_max, right_min = dfs(root.right)
# 更新最大最小值
_max = max(left_max, right_max, root.val)
_min = min(left_min, right_min, root.val)
res1 = (left_num, left_node, _max, _min)
res2 = (right_num, right_node, _max, _min)
# 第一种情况
if root.left == left_node and root.right == right_node and left_max < root.val < right_min:
return left_num+right_num+1, root, _max, _min
# 第二种情况
elif left_num < right_num:
return res2
elif left_num > right_num:
return res1
else:
if left_node.val > right_node.val:
return res1
else:
return res2
return dfs(root)[1]