您的位置:首页 > 其它

[LeetCode - 动态规划] 120. Triangle

2017-11-01 10:30 357 查看

1 题目

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.

For example, given the following triangle

[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]


The minimum path sum from top to bottom is
11
(i.e., 2 + 3 + 5 + 1 = 11).

Note:

Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.

2 题目分析

本题数据源很像一棵树,为了搜索最短路径,可以使用DFS。但是在搜索的过程中,寻求到达某一中间点k的最短路径需要知道到达其父节点的最短路径,根据题目要求,到达k的最短路径可能是从k的两个父节点引出的,设m是与k相邻的节点,那么m与k共享可能引出最短路径的父节点,所以如果单纯使用DFS,在求k与m的最短路径时,其父节点上的最短路径被求了两次,这就导致了重叠子问题

这个问题中,如果知道了节点k的两个子节点到树根的最短路径,节点k应该包含在值小的子路径中,即:

minPath = min(P1,P2) + k其中
P1,P2`是k的两个子节点的最短路径,这是这个问题的最优子结构,即可以由子问题推导出父问题的解

最后一行每一个节点的最短路径必须包含节点自身。

可以得出以下伪代码:

minPath 为一个长度为n的列表,初始化为最后一行的值
i in 从倒数第二行到第一行:
j in 每一行的从左到右:
minPath[i] = min(minPath[j], minPath[j+1]) + triangle[i][j]
minPath[0]就是要求的最短路径的值


3 Python源代码

# -*- encoding:utf-8 -*-

class Solution:
def minimumTotal(self, triangle):
"""
:type triangle: List[List[int]]
:rtype: int
"""
minSum = triangle[-1]
for i in range(len(triangle)-2,-1,-1):
for j in range(0,i+1):
minSum[j] = triangle[i][j] + min(minSum[j], minSum[j+1])
return minSum[0]

def main():
triangle = [
[2],\
[3,4],\
[6,5,7],\
[4,1,8,3] \
]
solution = Solution()
print(solution.minimumTotal(triangle))

if __name__ == '__main__':
main()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: