Triangle
题目描述
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.
解题方法
这种求最小的的题目,而且上下层之间是有关联的,一般可以往dp的方向想。 dp的四要素
- state
- function
- init state
- result
这里dp[i][j]
代表的是以triangle[i][j]为终点的路径的最小值,因为dp[i][j]的上面一层最多只有两种选择,
(在左边界和右边界时只有一种选择),所以就可以推出function是
dp[i][j] = min(dp[i-1][j-1], dp[i-1][j]) + triangle[i][j]
follow up
因为只有两层之间有联系,所以可以只用两个n为长度的array就可以
Solution
class Solution(object):
def minimumTotal(self, triangle):
"""
:type triangle: List[List[int]]
:rtype: int
"""
if not triangle:
return 0
rowNum = len(triangle)
dp = [[sys.maxint for i in range(rowNum)]for j in range(rowNum)]
dp[0][0] = triangle[0][0]
for i in range(1, rowNum):
for j in range(i+1):
if j == 0:
dp[i][0] = dp[i-1][0] + triangle[i][0]
elif j == i:
dp[i][j] = dp[i-1][j-1] + triangle[i][j]
else:
dp[i][j] = min(dp[i-1][j-1], dp[i-1][j]) + triangle[i][j]
minResult = sys.maxint
for i in range(rowNum):
if dp[rowNum-1][i] < minResult:
minResult = dp[rowNum-1][i]
return minResult
空间优化
注意,不能直接dp1=dp2
,因为这样它们指向的是同一个地址,那么dp2在变化的时候dp1指向的array也会
随着变化,就会导致结果不对,需要新建一个array,用dp1 = list(dp2)
class Solution(object):
def minimumTotal(self, triangle):
"""
:type triangle: List[List[int]]
:rtype: int
"""
if not triangle:
return 0
rowNum = len(triangle)
if rowNum == 1:
return triangle[0][0]
dp1 = [sys.maxint for i in range(rowNum)]
dp2 = [sys.maxint for i in range(rowNum)]
dp1[0] = triangle[0][0]
for i in range(1, rowNum):
for j in range(i+1):
if j == 0:
dp2[0] = dp1[0] + triangle[i][0]
elif j == i:
dp2[j] = dp1[j-1] + triangle[i][j]
else:
dp2[j] = min(dp1[j-1], dp1[j]) + triangle[i][j]
dp1 = list(dp2)
return min(dp2)