传递悄悄话 (100)
- 给定一个二叉树,节点采用顺序存储,如 i=0 表示根节点,2i + 1 表示左子树根,2i + 2 表示右子树根;
 - 每个节点站一个人,节点数值表示由父节点到该节点传递消息需要的时间;
 - 输出从根节点,将消息传递给所有的人需消耗的时间;
输入描述:
0 9 20 -1 -1 15 17 -1 -1 -1 -1 3 2 ;节点的顺序存储;-1表示空节点
输出描述:
所有的人都收到消息所消耗的时间 38 
示例1
 输入:
 0 9 20 -1 -1 15 17 -1 -1 -1 -1 3 2
 输出:
 38
示例2
 输入:
 0
 输出:
 0
示例3
 输入:
 0 9
 输出:
 9
说明:
 还原出二叉树如下
 
思路:
- 求二叉树的最大路径和;
 - BFS + 队列
 
class MaxPathSum:
    def solution(self, alist):
        # 广度优先入队
        queue = []
        queue.append((0, 0)) # 根节点入队  结构为-->(节点索引, 根节点到当前节点的路径和)
        result = 0 # 最大路径和
        while True:
            if len(queue) <= 0:
                break
            root_node = queue.pop(0)
            if self.is_leaf(root_node, alist):
                print("leaf:", root_node)
                result = max(result, root_node[1])
            else:
                # 继续找左子节点、右子节点
                left_node_idx = 2 * root_node[0] + 1
                if left_node_idx < len(alist) and alist[left_node_idx] != -1:
                    left_node_path_sum = alist[left_node_idx] + root_node[1]
                    # 新节点入队
                    queue.append((left_node_idx, left_node_path_sum))
                right_node_idx = 2 * root_node[0] + 2
                if right_node_idx < len(alist) and alist[right_node_idx] != -1:
                    right_node_path_sum = alist[right_node_idx] + root_node[1]
                    queue.append((right_node_idx, right_node_path_sum))
        print(result)
    def is_leaf(self, node, alist):
        node_idx = node[0]
        left_idx = 2 * node_idx + 1
        right_idx = 2 * node_idx + 2
        # 索引的有效性
        if left_idx >= len(alist):
            return True
        elif left_idx < len(alist) and right_idx >= len(alist):
            if alist[left_idx] == -1:
                return True
            return False
        else:
            # 索引均有效
            if alist[left_idx] != -1 or alist[right_idx] != -1:
                return False
            return True
if __name__ == '__main__':
    max_path_sum = MaxPathSum()
    while True:
        try:
            alist = list(map(int, input().strip().split()))
            max_path_sum.solution(alist)
        except KeyboardInterrupt:
            break
 



















