746. 使用最小花费爬楼梯(动态规划)(傻瓜教程)(python)(LC)

746. 使用最小花费爬楼梯

题目描述:

数组的每个索引作为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 costi。

每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以选择继续爬一个阶梯或者爬两个阶梯。

您需要找到达到楼层顶部的最低花费。在开始时,你可以选择从索引为 0 或 1 的元素作为初始阶梯。


示例 1:

输入: cost = [10, 15, 20]
输出: 15
解释: 最低花费是从cost[1]开始,然后走两步即可到阶梯顶,一共花费15

示例 2:

输入: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
输出: 6
解释: 最低花费方式是从cost[0]开始,逐个经过那些1,跳过cost[3],一共花费6

注意: cost 的长度将会在 [2, 1000]。 每一个 cost[i] 将会是一个Integer类型,范围为 [0, 999]。

解题

一、分析题目——最优子结构性质

对于每一个台阶,从底部到达其位置时所消耗的体力都必须是最少的

换句话说,每一个台阶都可以作为一“顶层台阶”


二、由该性质考虑到动态规划,尝试解题

1.划分阶段k——楼梯

每层楼梯对应不同的阶段,具体映射为k=cost列表索引

2.确定k阶段的状态变量x(k)——子最优解

与楼梯k有关的初始变量为cost值,但我们需要的x(k)是到达k阶楼梯到最优解

3.确定决策变量u(k)

决策变量应该与与楼梯k有关的初始变量有关(这个“有关”在一定程度上保证了无后效性)
事实上,u(k)=cost

4.确定状态转移方程x(k+1)=T(x(k),u(k))

既然已经判断出问题具有最优子结构性质,那也不难看出x(k)等于x(k-2)+cost[k-2]与x(k-1)+cost[k-1]中较小的那一个
即:
x(k)=min(x(k-2)+cost[k-2], x(k-1)+cost[k-1])

5.勿忘起始量

由于可以选择下标 0或1 作为初始阶梯,因此有
x(0)=x(1)=0


三、码代码

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:

1.找k(因为存在顶层阶梯,所以上线为cost表长+1)

		n = len(cost)

2.创建列表(因为存在顶层阶梯,所以上线为cost表长+1)

		x = [0]*(n+1)

3.循环,填表,返回答案

		for k in range(2,n+1):
			x[k]=min(x(k-2)+cost[k-2], x(k-1)+cost[k-1])
		return x[n]

完整代码

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
   		n = len(cost)
   		x = [0]*(n+1)
		for k in range(2,n+1):
			x[k]=min(x(k-2)+cost[k-2], x(k-1)+cost[k-1])
		return x[n]

四、分析

1.时间复杂度O(n)

遍历cost

2.空间复杂度O(n)

x列表长n+1


五、优化

通过滚动列表优化空间复杂度

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        n = len(cost)
        prev = curr = 0
        for i in range(2, n + 1):
            nxt = min(curr + cost[i - 1], prev + cost[i - 2])
            prev, curr = curr, nxt
        return curr

空间复杂度O(1)



动态规划模版

动态规划模版链接

你可能感兴趣的:(傻瓜教程(LC),python,动态规划,算法,leetcode,数据结构)