# -*- coding: utf-8 -*-
'''
Python程序员面试算法宝典---解题总结: 第三章 二叉树 3.4 如何求一棵二叉树的最大子树和
题目:
给定一棵二叉树,它的每个节点都是正整数或负整数,如何找到一棵子树,使得它所有节点的
和最大
分析:
举例如下,假设有一棵二叉树如下
-3
2 -1
-1 4 4 5
那么求最大子树和,必然要求这颗最大子树的根节点。
要求一棵子树的结点和,就需要先求出该子树的左孩子为根节点的子树的结点和,
和该子树的右孩子为根节点的子树的结点和。
这种情况是典型的递归做法。
那么在求解的过程中需要记录一个maxSum和maxRoot来保存
求解出leftMax, rightMax,然后计算以当前节点node为根节点的子树和
leftMax + rightMax + node.data
关键:
1
求解出以root为根节点的子树的所有节点和
注意更新的最大值如果用局部变量会有问题,
所以用类中的全局变量
注意: 整颗树也是作为一颗子树
2 代码
class SubTree(object):
def __init__(self):
self.maxSum = float('-inf')
self.maxRoot = None
def maxSumTree(self, root):
if not root:
return 0
maxLeft = self.maxSumTree(root.left)
maxRight = self.maxSumTree(root.right)
sum = maxLeft + maxRight + root.data
if sum > self.maxSum:
self.maxSum = sum
self.maxRoot = root
# 返回以当前结点为根节点的子树的所有结点和
return sum
参考:
Python程序员面试算法宝典
'''
class BinaryTreeNode(object):
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
def buildTree(data):
if not data:
return
nodes = list()
for value in data:
node = BinaryTreeNode(value)
nodes.append(node)
# 构建二叉树
length = len(data)
for i in range(length / 2):
node = nodes[i]
if not node:
continue
if 2*i + 1 < length:
node.left = nodes[2*i + 1]
if 2*i + 2 < length:
node.right = nodes[2*i + 2]
return nodes[0]
# def maxSumTree(root, maxSum, maxRoot):
# if not root:
# return
# maxLeft = maxSumTree(root.left, maxSum, maxRoot)
# maxRight = maxSumTree(root.right, maxSum, maxRoot)
# if maxLeft is None and maxRight is None:
# return root.data
# elif maxRight is None:
# if maxLeft > maxSum:
# maxSum = maxLeft
# maxRoot = root.left
# elif maxLeft is None:
# if maxRight > maxSum:
# maxSum = maxRight
# maxRoot = root.right
# else:
# if maxLeft > maxRight:
# if maxLeft > maxSum:
# maxSum = maxLeft
# maxRoot = root.left
# else:
# if maxRight > maxSum:
# maxSum = maxRight
# maxRoot = root.right
'''
求解出以root为根节点的子树的所有节点和
注意更新的最大值如果用局部变量会有问题,
所以用类中的全局变量
注意: 整颗树也是作为一颗子树
'''
class SubTree(object):
def __init__(self):
self.maxSum = float('-inf')
self.maxRoot = None
def maxSumTree(self, root):
if not root:
return 0
maxLeft = self.maxSumTree(root.left)
maxRight = self.maxSumTree(root.right)
sum = maxLeft + maxRight + root.data
if sum > self.maxSum:
self.maxSum = sum
self.maxRoot = root
# 返回以当前结点为根节点的子树的所有结点和
return sum
def process():
data = [-3, 2, -1, -1, 4, 4, 5]
root = buildTree(data)
subTree = SubTree()
subTree.maxSumTree(root)
result = subTree.maxSum
print result
print subTree.maxRoot.data
if __name__ == "__main__":
process()