'''
Description: 746.使用最小花费爬楼梯
Autor: 365JHWZGo
Date: 2021-11-15 09:09:47
LastEditors: 365JHWZGo
LastEditTime: 2021-11-15 15:09:36
'''
class Solution(object):
def minCostClimbingStairs(self, cost):
"""
:type cost: List[int]
:rtype: int
"""
# method:
# 记录最小代价
minCost = sum(cost)
# 获取cost数组的长度,因为每一次可以爬一步或者两步,所以最多爬costL步
costL = len(cost)
# 创建并初始化dp数组
dp = [[minCost for i in range(costL+1)]for j in range(costL+1)]
dp[0][0] = 0
# 这里不推荐使用dp[[0]*(costL+1)]*(costL+1),因为这样会引起改变一个值时另一个值也会跟着发生改变
for i in range(costL):
dp[i+1][0] = i+1
for j in range(costL):
dp[0][j+1] = cost[j]
# print(dp)
# 具体实现过程
for i in range(0, costL):
for j in range(i, i*2+1):
if j<= costL-1:
dp[i+1][j+1] = min(dp[i][j]+dp[0][j+1], dp[i+1][j+1])
if j<=costL-2:
dp[i+1][j+2] = min(dp[i][j]+dp[0][j+2], dp[i+1][j+2])
if minCost>dp[i+1][costL-1] or minCost>dp[i+1][costL]:
minCost = min(dp[i+1][costL-1],dp[i+1][costL])
if j>costL:
break
return minCost
结果不是很理想
执行p.minCostClimbingStairs([1, 100, 1, 1, 1, 100, 1, 1, 100, 1])打印出它的dp数组来看
[[0, 1, 100, 1, 1, 1, 100, 1, 1, 100, 1],
[1, 1, 100, 307, 307, 307, 307, 307, 307, 307, 307],
[2, 307, 101, 2, 101, 307, 307, 307, 307, 307, 307],
[3, 307, 307, 102, 3, 3, 201, 307, 307, 307, 307],
[4, 307, 307, 307, 103, 4, 103, 4, 202, 307, 307],
[5, 307, 307, 307, 307, 104, 104, 5, 5, 104, 203],
[6, 307, 307, 307, 307, 307, 204, 105, 6, 105, 6],
[7, 307, 307, 307, 307, 307, 307, 205, 106, 106, 7],
[8, 307, 307, 307, 307, 307, 307, 307, 206, 206, 107],
[9, 307, 307, 307, 307, 307, 307, 307, 307, 306, 207],
[10, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307]]
有将近一半的位置空闲,那么我们来优化一下数组吧!
class Solution(object):
def minCostClimbingStairs(self, cost):
"""
:type cost: List[int]
:rtype: int
"""
# method:
# 记录最小代价
minCost = sum(cost)
dp = [minCost for i in range(len(cost))]
dp[0],dp[1]= cost[0],cost[1]
for i in range(2,len(cost)):
if dp[i]>dp[i-2]+cost[i] or dp[i]>dp[i-1]+cost[i]:
dp[i] = min(dp[i-2]+cost[i],dp[i-1]+cost[i])
print(dp)
return min(dp[-1],dp[-2])
经过代码1的方案,我们得知,并不需要将所有的代价都计算出来,只需要维护爬到当前楼梯的最小代价,所以这次只需要用一个一维的数组解决问题。
且由题得:
- 爬到当前第i阶楼梯一定是由第i-1阶楼梯或第i-2阶楼梯来的,所以只需要比较dp[i]>dp[i-2]+cost[i] or dp[i]>dp[i-1]+cost[i]哪一个更小,那么便将dp[i]的代价变成那个最小代价。
- 由此这道题ko了。
----附加--------
刚刚又翻到网友更为简洁的版本,直接在原数组上修改值,使得空间又节省了不少!!!!
class Solution(object):
def minCostClimbingStairs(self, cost):
"""
:type cost: List[int]
:rtype: int
"""
for i in range(2,len(cost)):
cost[i] += min(cost[i-1],cost[i-2])
return min(cost[-1],cost[-2])