動態規劃] 120. Triangle
阿新 • • 發佈:2019-01-23
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()