传递悄悄话 (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