# -*- coding: utf-8 -*-
'''
Python程序员面试算法宝典---解题总结: 第三章 二叉树 3.13 如何在二叉树中找出路径最大的和
题目:
给定一棵二叉树,求各个路径的最大和,路径可以以任意结点作为起点和终点。比如给
定以下二叉树:
2
5 3
最大和的路径为结点5->2->3,这条路径的和为10,因此返回10。
分析:
上面举的例子太简单,无法分析出有效情况。
-2
2 4
1 -5 1 -10
分析可知,最大路径和必的路径必须是连在一起的。
不能断开某个结点。
这个看上去有点像动态规划或者回溯。
max=root + root左子树的最大值 + root右子树的最大值。
之前有一个求最大连续子数组和和这个问题很像。
当时的解法如下:
假设f[i]表示以第i个数字结尾的最大连续子数组和,
那么就有:
f[i] = { arr[i], i =0 或者 f[i-1] < 0
{ f[i-1] + arr[i], f[i-1] > 0
关键:
1 书上解法
先求出以roo.left为起始节点,到叶子节点为终点的最大路径和maxLeft;
同理求出maxRight;
则最长路径可能为3种情况:
leftMax - root.data + maxLeft
rightMax = root.data + maxRight
allMax = root.data + leftMax + rightMax
此时将tmpMax = max(leftMax, rightMax, allMax)
与之前记录的maxiu,比较,如果maximum < tmpMax,则令maxiu, = tmpMax
2 我之所以没有想出来,是因为
没有想到是从3个leftMax, rightMax, allMax中选择最大的
参考:
Python程序员面试算法宝典
'''
class BinaryTreeNode(object):
def __init__(self, data, left=None, right=None):
self.data = data
self.right = right
self.left = left
def buildTree(data):
if not data:
return
nodes = list()
for value in data:
node = BinaryTreeNode(value)
nodes.append(node)
size = len(data)
for i in range(size / 2):
if not nodes[i]:
continue
if 2 * i + 1 < size:
nodes[i].left = nodes[2 * i + 1]
if 2 * i + 2 < size:
nodes[i].right = nodes[2 * i + 2]
return nodes[0]
class MyTree(object):
def __init__(self):
self.max = float('-inf')
def findMax(self, root):
if not root:
return 0
leftValue = self.findMax(root.left)
rightValue = self.findMax(root.right)
leftMax = leftValue + root.data
rightMax = rightValue + root.data
allMax = leftValue + rightValue + root.data
tmpMax = max(leftMax, rightMax, allMax)
if tmpMax > self.max:
self.max = tmpMax
return tmpMax
def process():
data = [-2, 2, 4, 1, -5, 1, -10]
root = buildTree(data)
tree = MyTree()
tree.findMax(root)
print tree.max
if __name__ == "__main__":
process()