leetcode-pp / 91alg-5-daily-check

91 天学算法第五期打卡
55 stars 14 forks source link

【Day 54 】2021-11-02 - 746.使用最小花费爬楼梯 #73

Open azl397985856 opened 2 years ago

azl397985856 commented 2 years ago

746.使用最小花费爬楼梯

入选理由

暂无

题目地址

https://leetcode-cn.com/problems/min-cost-climbing-stairs/

前置知识

每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯。

请你找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为 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] 将会是一个整型数据,范围为 [0, 999] 。

ai2095 commented 2 years ago

746. Min Cost Climbing Stairs

https://leetcode.com/problems/min-cost-climbing-stairs/

Topics

思路

DP

代码 Python

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        len_cost = len(cost)
        dp = [float("inf")] * 3
        dp[0], dp[1] = cost[0], cost[1]
        for i in range(2, len_cost):
            j = i % 3
            dp[j] = min(dp[j-2], dp[j-1]) + cost[i]
        return min(dp[(len_cost-2)%3], dp[(len_cost-1)%3])

复杂度分析

时间复杂度: O(N)
空间复杂度:O(1)

renxumei commented 2 years ago
/**
 * @param {number[]} cost
 * @return {number}
 * dp[i]=min(dp[i-1],dp[i-2])+cost[i]
 */
var minCostClimbingStairs = function(cost) {
    let n = cost.length;
    if (!cost || n === 0) {
        return 0;
    }
    let dp = new Array(n + 1);
    dp[0] = cost[0];
    dp[1] = cost[1];
    for(let i=2; i<n+1; i++) {
        dp[i] = Math.min(dp[i-1],dp[i-2]) + (i === n ? 0 : cost[i])
    }
    return dp[n]
};
Serena9 commented 2 years ago

代码

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        dp = [0] * (len(cost)+1)
        dp[0], dp[1] = cost[0], cost[1]
        for i in range(2, len(cost)+1):
            dp[i] = min(dp[i-1], dp[i-2]) + (cost[i] if i != len(cost) else 0)
        return dp[-1]
laofuWF commented 2 years ago
# time: O(N)
# space: O(1)

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:        
        prev1 = cost[0]
        prev2 = cost[1]

        for i in range(2, len(cost)):
            curr = min(prev1, prev2) + cost[i]
            prev1 = prev2
            prev2 = curr

        return min(prev1, prev2)
learning-go123 commented 2 years ago

思路

代码

Go Code:


func minCostClimbingStairs(cost []int) int {
    for i := range cost {
        if i <= 1 {
            continue
        }

        cost[i] = min(cost[i-1], cost[i-2]) + cost[i]
    }
    return min(cost[len(cost)-1], cost[len(cost)-2])
}

func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}

复杂度分析

令 n 为数组长度。

ychen8777 commented 2 years ago

思路

记忆化搜索

代码


class Solution {
    public int minCostClimbingStairs(int[] cost) {

        if (cost.length == 0) {
            return 0;
        }

        if (cost.length == 1) {
            return cost[0];
        }

        int[] minCosts = new int[cost.length];

        minCosts[0] = cost[0];
        minCosts[1] = cost[1];
        for (int i = 2; i < cost.length; i++) {
            minCosts[i] = cost[i] + Math.min(minCosts[i-1], minCosts[i-2]);
        }

        return Math.min(minCosts[minCosts.length-1], minCosts[minCosts.length-2]);

    }
}

复杂度

时间: O(n) \ 空间: O(n)

m-z-w commented 2 years ago
var minCostClimbingStairs = function(cost) {
    const dp = []
    dp[0] = cost[0]
    dp[1] = cost[1]
    const length = cost.length
    for (let i = 2; i < length; i++) {
        dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i]
    }
    return Math.min(dp[length - 1], dp[length - 2])
};

时间:O(n) 空间:O(n)

watermelonDrip commented 2 years ago
class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        dp  = [0]*(len(cost))
        dp[0] = cost[0]
        dp[1] = cost[1]
        if len(cost) == 2:
            return min(cost)
        for i in range(2, len(cost)):
            dp[i] = min(dp[i-1]+cost[i],dp[i-2]+cost[i])
        return min(dp[-1],dp[-2])
xyinghe commented 2 years ago
class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        n = len(cost)
        dp = [0] * (n + 1)
        for i in range(2, n + 1):
            dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])
        return dp[n]
chenming-cao commented 2 years ago

解题思路

DP。临界条件是minCosts[0] = 0, minCosts[1] = 0。状态转移方程是minCosts[i] = min(minCosts[i - 2] + cost[i - 2], minCosts[i - 1] + cost[i - 1]),即上到Step i的花费为从Step(i - 2)上两步的花费和从Step(i - 1)上一步的花费的最小值。

代码

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        // Use an array of size n + 1 to store the minimum costs
        int[] minCosts = new int[n + 1];
        // Base cases: we can either start from index 0 or index 1, no costs for these
        minCosts[0] = 0;
        minCosts[1] = 0;
        for (int i = 2; i < n + 1; i++) {
            // minimum cost at step i is the smaller one of the cost climing 2 steps from step (i - 2) and the cost climing 1 step from step (i - 1)
            minCosts[i] = Math.min(minCosts[i - 2] + cost[i - 2], minCosts[i - 1] + cost[i - 1]);
        }
        return minCosts[n];
    }
}

复杂度分析

yiwchen commented 2 years ago

It's DP time! (say it as if you are saying it's morphin time)

压缩一下维度可以让空间更小!

Java:

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int dp[] = new int[2];

        for (int i = 2; i <cost.length + 1; i++){
            int temp = dp[0];
            dp[0] = Math.min(dp[0] + cost[i - 1], dp[1] + cost[i - 2]);
            dp[1] = temp;
        }
        return dp[0];
    }
}

SC: O(1) TC: O(n)

WeiWri-CC commented 2 years ago

python

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        i = len(cost)
        dp = [0] * (i + 1)
        dp[0] = 0
        dp[1] = 0

        for j in range(2, i + 1):
            dp[j] = min(dp[j-1] + cost[j-1], dp[j-2] + cost[j-2])

        return dp[-1]
Huangxuang commented 2 years ago

题目:Min Cost Climbing Stairs

思路

minCost[i] = min(minCost[i-1] + cost[i], minCost[i-2] + cost[i-1])。

台阶的数组从0开始计数。可以用-1代表地面,并设cost[-1] = 0。

最小总花费的初始值为:

第0级台阶: minCost[0] = min(cost[-1], cost[0]) = min(0, cost[0]) = 0,

第1级台阶: minCost[1] = min(cost[0], cost[1])

作者:armeria-program 链接:https://leetcode-cn.com/problems/min-cost-climbing-stairs/solution/yi-bu-yi-bu-tui-dao-dong-tai-gui-hua-de-duo-chong-/

代码

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        // int[] res = new int[cost.length];
        // res[0] = 0;
        // res[1] = Math.min(cost[0], cost[1]);
        // for (int i = 2; i < cost.length; i++) {
        //     res[i] = Math.min(res[i - 1] + cost[i], res[i - 2] + cost[i - 1]);
        // }
        // return res[res.length - 1];

        int res0 = 0;
        int res1 = Math.min(cost[0], cost[1]);
        int res = 0;
        for (int i = 2; i < cost.length; i++) {
            res = Math.min(res1 + cost[i], res0 + cost[i- 1]);
            res0 = res1;
            res1 = res;
        }

        return res1;

    }
}

复杂度分析

biscuit279 commented 2 years ago

思路:取前i-1与i-2的最小值加上第i阶台阶

class Solution(object):
    def minCostClimbingStairs(self, cost):
        """
        :type cost: List[int]
        :rtype: int
        """
        dp=[0]*(len(cost)+1)
        dp[0],dp[1]=cost[0],cost[1]
        for i in range(2,len(cost)+1):
            if i!=len(cost):
                dp[i] = min(dp[i-1],dp[i-2]) + cost[i]
            else:
                dp[i] = min(dp[i-1],dp[i-2])
        return dp[-1]

时间复杂度:O(N) 空间复杂度:O(N)

Yufanzh commented 2 years ago

Intuition

DP approach\ define dp function minCost[i] means the minimum cost when reach to ith steps. It can be accomplished from two approaches:\ approach 1. from i - 1th step, minCost[i - 1] + cost[i]\ approach 2. from i - 2th step, minCost[i - 2] + cost[i]\ Then minCost[i] = min(approach 1, approach 2)

Algorithm in python3

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

Complexity Analysis

xieyj17 commented 2 years ago
class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        n = len(cost)
        dp_cost = [0]*(n+1)
        for i in range(2,n+1):
            t1 = dp_cost[i-1] + cost[i-1]
            t2 = dp_cost[i-2] + cost[i-2]
            dp_cost[i] = min(t1, t2)
        return dp_cost[-1]

Time: O(N)

Space: O(N)

xinhaoyi commented 2 years ago

746. 使用最小花费爬楼梯

数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值 cost[i](下标从 0 开始)。

每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯。

请你找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为 0 或 1 的元素作为初始阶梯。

思路一

这一题的核心是每一步都有越级和不越级的两种选择,然后要达到最后总体力值消耗最少的结果,很容易联想到使用动态规划,列出状态转移方程即可。

这题题意要审清,选择 cost[0] 作为初始阶梯,是指我人还在地面上,要付出cost[0]的体力值,才能到0号阶梯顶部,也就是登上0号阶梯

选择cost[1]作为初始阶梯,是指我人就踩在0号阶梯上,也就是在0号阶梯的顶部,要再付出cost[1]的体力值才能登上1号阶梯

要登上i号阶梯,怎么花最少的体力呢?

有两种情况,第一种是先花最少的体力登上i - 1号阶梯,再花cost[i]登上i号阶梯 minTotalCost[i - 1] + cost[i]

第二种是想花最少体力登上 i - 2 号阶梯,再花 cost[i - 1] 的体力越级直接登上i号阶梯 minTotalCost[ i - 2] + cost[i - 1]

minTotalCost[i] 指登上i号阶梯一共需要的最少体力值,取上述两种情况中更小的一个

minTotalCost[i] = min{minTotalCost[i - 1] + cost[i] , minTotalCost[ i - 2] + cost[i - 1]}

我们再找出minTotalCost[0]和minTotalCost[1]的值,然后就可以从2开始不断往后递推

minTotalCost[0] ,即登上 0 号台阶需要花的最少总体力值,要么从地面出发 付出cost[0],要么直接站在0号台阶顶部,花费0

所以minTotalCost[0] = min{cost[0] , 0} = 0

minTotalCost[1] 要么从地面出发,付出cost[0]后越级直接登上1号台阶,要么从0号台阶(顶部)出发,付出cost[1]后直接到达1号台阶

所以minTotalCost[1] = min{cost[1] , cost[2]}

代码

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        /**
        这一题的核心是每一步都有越级和不越级的两种选择,然后要达到最后总体力值消耗最少的结果,很容易联想到使用动态规划,列出状态转移方程即可。
        这题题意要审清,选择 cost[0] 作为初始阶梯,是指我人还在地面上,要付出cost[0]的体力值,才能到0号阶梯顶部,也就是登上0号阶梯
        选择cost[1]作为初始阶梯,是指我人就踩在0号阶梯上,也就是在0号阶梯的顶部,要再付出cost[1]的体力值才能登上1号阶梯
        要登上i号阶梯,怎么花最少的体力呢?
        有两种情况,第一种是先花最少的体力登上i - 1号阶梯,再花cost[i]登上i号阶梯 minTotalCost[i - 1] + cost[i]
        第二种是想花最少体力登上 i - 2 号阶梯,再花 cost[i - 1] 的体力越级直接登上i号阶梯 minTotalCost[i - 2] + cost[i - 1]
        minTotalCost[i] 指登上i号阶梯一共需要的最少体力值,取上述两种情况中更小的一个
        minTotalCost[i] = min{minTotalCost[i - 1] + cost[i] , minTotalCost[ i - 2] + cost[i - 1]}
        我们再找出minTotalCost[0]和minTotalCost[1]的值,然后就可以从2开始不断往后递推
        minTotalCost[0] ,即登上 0 号台阶需要花的最少总体力值,要么从地面出发 付出cost[0],要么直接站在0号台阶顶部,花费0
        所以minTotalCost[0]  = min{cost[0] , 0} = 0
        minTotalCost[1] 要么从地面出发,付出cost[0]后越级直接登上1号台阶,要么从0号台阶(顶部)出发,付出cost[1]后直接到达1号台阶
        所以minTotalCost[1] = min{cost[1] , cost[2]}
         */

        //解法一
        //楼梯个数
         int size = cost.length;
         //创建最小总花费数组
         int[] minTotalCost = new int[size];
         minTotalCost[0] = 0;
         minTotalCost[1] = Math.min(cost[0],cost[1]);//题目说了cost 的长度范围是 [2, 1000]
         for(int i = 2; i < size; i++){
             minTotalCost[i] = Math.min(minTotalCost[i-1] + cost[i] , minTotalCost[i-2] + cost[i-1]);
         }
         return minTotalCost[size - 1];

    }
}

复杂度分析

时间复杂度:$O(n)$

空间复杂度:$O(n)$

思路二

在思路一的基础上优化代码,我们目前借助了一个辅助数组minTotalCost[] ,空间复杂度为O(n),这个可以优化

注意到状态转移方程的每一步都只涉及三个变量,我们可以去掉数组,只维护这三个变量,并不断更新,效果是一样的

代码

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        //解法二
        //在解法一的基础上优化代码

        //楼梯个数
        int size = cost.length;

        int minTotalCost0 = 0; //minTotalCost[0] = 0;
        int minTotalCost1 = Math.min(cost[0],cost[1]); //minTotalCost[1] = Math.min(cost[0],cost[1])

        //需要的答案
        //debug: 注意这里不能写成minTotalCost2 = 0,初值一定要和minTotalCost1相等
        //否则,如果就只有两个楼梯,底下的for循环是直接跳过的,那么你的最小总花费岂不是0了,这就不行
        int minTotalCost2 = minTotalCost1;

        for(int i = 2; i < size; i++){
            minTotalCost2 = Math.min(minTotalCost1 + cost[i] , minTotalCost0 + cost[i-1]);
            minTotalCost0 = minTotalCost1;
            minTotalCost1 = minTotalCost2;
        }
        return minTotalCost2;
    }
}

复杂度分析

时间复杂度:$O(n)$

空间复杂度:$O(1)$

chaggle commented 2 years ago

title: "Day 54 746. 使用最小花费爬楼梯" date: 2021-11-02T12:23:08+08:00 tags: ["Leetcode", "c++", "DP"] categories: ["91-day-algorithm"] draft: true


746. 使用最小花费爬楼梯

题目

数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值 cost[i](下标从 0 开始)。

每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯。

请你找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为 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] 将会是一个整型数据,范围为 [0, 999] 。

题目思路

  • 1、跟斐波那契是一样的动态规划题目,由于有爬一层跟爬两层的选择,所以只需要返回数组最后两个值中较小的那一个即可。
class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        int dp[2];
        dp[0] = cost[0];
        dp[1] = cost[1];

        for(int i = 2; i < n; i++)
        {
            int mix = min(dp[0], dp[1]) + cost[i];
            dp[0] = dp[1];
            dp[1] = mix;
        }

        return min(dp[0], dp[1]);
    }
};

复杂度

QiZhongdd commented 2 years ago
var minCostClimbingStairs = function(cost) {
    if(cost===null||cost.length==0){
        return 0;
    }
    const dp=[];
    dp[0]=cost[0];
    dp[1]=cost[1];
    for(let i=2;i<=cost.length;i++){
        dp[i]=Math.min(dp[i-2],dp[i-1])+ (i == cost.length ? 0 : cost[i]);
    }
    return dp[cost.length]
};
ghost commented 2 years ago

题目

  1. Min Cost Climbing Stairs

思路

DP

代码

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

        dp = [0] * 3
        dp[0], dp[1] = cost[0], cost[1]

        for i in range(2, n+1):
            if i == n:
                dp[-1] = min(dp[0], dp[1])
            else:
                dp[-1] = min(dp[0], dp[1]) + cost[i]

            dp[0] = dp[1]
            dp[1] = dp[2]

        return dp[-1]

复杂度

Space: O(1) Time: O(n)

RocJeMaintiendrai commented 2 years ago

题目

https://leetcode-cn.com/problems/min-cost-climbing-stairs/

思路

DP, 到达当前台阶i花费最小dp[i],或到达i-1最小花费dp[i-1],那么minCost [i] = min(dp[i], dp[i - 1]).

代码

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int f1 = 0;
        int f2 = 0;
        for(int i = cost.length - 1; i >= 0; i--) {
            int f0 = cost[i] + Math.min(f1, f2);
            f2 = f1;
            f1 = f0;
        }
        return Math.min(f1, f2);
    }
}

复杂度分析

时间复杂度

O(n)

空间复杂度

O(1)

ginnydyy commented 2 years ago

Solution

todo

zhangyalei1026 commented 2 years ago

思路

定义好状态方程,初始化dp值,用dp方程

代码

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        # state dp[i] 代表到第i个台阶所用的最小的cost
        n = len(cost)
        dp = [0] * n
        # initialize
        dp[0] = cost[0]
        dp[1] = cost[1]
        # function
        for i in range(2, n):
            dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]
        return min(dp[n - 1], dp[n -2])

复杂度分析

时间复杂度:O(n) 空间复杂度:O(n)

leolisgit commented 2 years ago

题目

https://leetcode.com/problems/min-cost-climbing-stairs/

思路

爬到顶的cost是由倒数第一步的最小cost和倒数第二步的最小cost决定。

代码

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        if (cost.length < 2) {
            return cost[0];
        }
        int[] dp = new int[cost.length];

        dp[0] = cost[0];
        dp[1] = cost[1];

        for (int i = 2; i < cost.length; i++) {
            dp[i] = Math.min(dp[i - 1] + cost[i], dp[i - 2] + cost[i]);
        }

        return Math.min(dp[cost.length - 1], dp[cost.length - 2]);
    }
}

复杂度

时间:O(n)
空间:O(n)

doveshnnqkl commented 2 years ago

思路

动态规划

代码

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        int[] dp = new int[n + 1];
        dp[0] = dp[1] = 0;
        for (int i = 2; i <= n; i++) {
            dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
        }
        return dp[n];
    }
}

复杂度

时间复杂度:O(n) 空间复杂度:O(n)

siyuelee commented 2 years ago
class Solution(object):
    def minCostClimbingStairs(self, cost):
        dp = [0 for _ in range(len(cost) + 1)]
        for i in range(len(cost) + 1):
            if i == 0:
                dp[i] = 0
            elif i == 1:
                dp[i] = 0
            else:
                dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2])
        return dp[-1]

T: O(N) S: O(N)

wenlong201807 commented 2 years ago

代码块


var minCostClimbingStairs = function (cost) {
  const dp = [cost[0], cost[1]];

  for (let i = 2; i < cost.length; ++i) {
    dp[i] = Math.min(dp[i - 1] + cost[i], dp[i - 2] + cost[i]);
  }

  return Math.min(dp[cost.length - 1], dp[cost.length - 2]);
};

时间复杂度和空间复杂度

Zhang6260 commented 2 years ago

JAVA版本

思路:

主要的思想为使用动态规划来完成,能够爬到某一层楼梯最小花费等价与爬到前二层加上他们当层的代价的最小值,于是状态转移方程就变成了 dp[i] = Math.min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);又因为这是和前两个的状态有关的,所有可以只使用二个变量来存储,这样空间复杂度就降为了O(1)。

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n=cost.length;
        int cout=0;
        int prev = 0, curr = 0;
        for(int i=2;i<=n;i++){
           int next = Math.min(curr + cost[i - 1], prev + cost[i - 2]);
            prev = curr;
            curr = next;
        }
    return curr;
    }
}

时间复杂度:O(n)

空间复杂度:O(1)

falconruo commented 2 years ago

思路: 动态规划,dp[n] = min(dp[n - 1) + cost[n - 1], dp[n - 2] + cost[n - 2]), 使用两个变量记录dp[n - 1]和dp[n - 2]的值,初始值dp[0] = dp[1] = 0

复杂度分析:

代码(C++):

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        int dp1 = 0, dp2 = 0;

        for (int i = 2; i <= n; ++i) {
            int tmp = min(dp1 + cost[i - 1], dp2 + cost[i - 2]);
            dp2 = dp1;
            dp1 = tmp;
        }

        return dp1 ;
    }
};
Jinjin680 commented 2 years ago

思路

递归代码

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        vector<int> cache(cost.size());
        return min(help(cost, 0, cache), help(cost, 1, cache));
    }
    int help(vector<int>& cost, int index, vector<int>& cache){
        if(index >= cost.size()) return 0; //到达递归末尾
        if(cache[index]) return cache[index]; //如果该点已经计算过,不再计算
        int take1step = help(cost, index + 1, cache);
        int take2step = help(cost, index + 2, cache);
        cache[index] = min(take1step, take2step) + cost[index];
        return cache[index];
    }
};

复杂度分析

carsonlin9996 commented 2 years ago

思路

dp + 滚动数组记录 dp 方程 dp[i] = cost[i] + min(dp[i - 1], dp[i - 2]).

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        if (cost.length == 1) {
            return cost[0];
        }
        if (cost.length == 2) {
            return Math.min(cost[0], cost[1]);
        }
        int[] dp = new int[3];

        dp[0] = cost[0];
        dp[1] = cost[1];

        for (int i = 2; i < cost.length; i++) {
            dp[i % 3] = cost[i] + Math.min(dp[(i - 1) % 3], dp[(i - 2) % 3]);
        }

        return Math.min(dp[(cost.length - 1) % 3], dp[(cost.length - 2) % 3]);

    }
}

复杂度分析 时间复杂度:O(n) 空间复杂度:O(n)

jiahui-z commented 2 years ago

思路: maintain a array for the minimum cost to reach to each step

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int[] dp = new int[cost.length+1]; // dp[i] is the minimum cost to reach ith step
        dp[0] = 0;
        dp[1] = 0;

        for (int i = 2; i <= cost.length; i++) {
            dp[i] = Math.min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]); 
        }

        return dp[cost.length];
    }
}

Time Complexity: O(n) Space Complexity: O(1)

xuanaxuan commented 2 years ago
class Solution {
    public int minCostClimbingStairs(int[] cost) {

        if (cost == null || cost.length == 0)
            return 0;

        int[] dp = new int[cost.length + 1];
        dp[0] = cost[0];
        dp[1] = cost[1];

        for(int i = 2; i <= cost.length; i++)
            dp[i] = Math.min(dp[i - 1], dp[i - 2]) + (i == cost.length ? 0 : cost[i]);

        return dp[cost.length];
    }
}
zol013 commented 2 years ago
class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        dp = [0] * (len(cost)+1)
        dp[0], dp[1] = cost[0], cost[1]
        for i in range(2, len(cost)+1):
            dp[i] = min(dp[i-1], dp[i-2]) + (cost[i] if i != len(cost) else 0)
        return dp[-1]

TC:O(N) SC:O(N)

AnhTom2000 commented 2 years ago

思路

假设数组 cost 的长度为 n,则 n 个阶梯分别对应下标 0 到 n−1,楼层顶部对应下标 n,问题等价于计算达到下标 n 的最小花费。可以通过动态规划求解。

创建长度为 n+1 的数组 dp,其中dp[i] 表示达到下标 ii 的最小花费。

由于可以选择下标 0 或 1 作为初始阶梯,因此有dp[0]=dp[1]=0。

依次计算 dp 中的每一项的值,最终得到的 dp[n] 即为达到楼层顶部的最小花费。

代码:Java

class Solution {
    public int minCostClimbingStairs(int[] cost) {
      int n = cost.length;
      int[] dp = new int[n+1];
      dp[0] = dp[1] = 0;
      for(int i = 2;i<=n;i++){
        dp[i] = Math.min(cost[i-1] + dp[i-1] , cost[i-2] + dp[i-2]);
      }
      return dp[n];
    }
}

复杂度分析

时间复杂度:O(n)

空间复杂度:O(n)

标签

数组,动态规划

zhangzhengNeu commented 2 years ago

思路: 动态规划,dp[n] = min(dp[n - 1) + cost[n - 1], dp[n - 2] + cost[n - 2]), 使用两个变量记录dp[n - 1]和dp[n - 2]的值,初始值dp[0] = dp[1] = 0

复杂度分析:

时间复杂度: O(N), N为楼梯层数 空间复杂度: O(1) 代码(C++):

class Solution { public: int minCostClimbingStairs(vector& cost) { int n = cost.size(); int dp1 = 0, dp2 = 0;

    for (int i = 2; i <= n; ++i) {
        int tmp = min(dp1 + cost[i - 1], dp2 + cost[i - 2]);
        dp2 = dp1;
        dp1 = tmp;
    }

    return dp1 ;
}

};

A-PolarBear commented 2 years ago

class Solution {
    public int minCostClimbingStairs(int[] cost) {

        if (cost == null || cost.length == 0)
            return 0;

        int[] dp = new int[cost.length + 1];
        dp[0] = cost[0];
        dp[1] = cost[1];

        for(int i = 2; i <= cost.length; i++)
            dp[i] = Math.min(dp[i - 1], dp[i - 2]) + (i == cost.length ? 0 : cost[i]);

        return dp[cost.length];
    }
}
chen445 commented 2 years ago

思路

Solution1 : We used an array to store the min_cost arrived at index i.

Solution2: At each stairs, we have two choices, we can either chose step 1, or step 2. We recursively check both of them, and take the min_cost.

代码

Solution 1:

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        dp=[float('inf')]*(len(cost)+1)
        dp[0]=0
        dp[1]=0
        for i in range(2,len(cost)+1):
            dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2])
        return dp[len(cost)]      

Solution2

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        memo = {}
        def dfs(cur_stair):
            if cur_stair >= len(cost):
                return 0

            cur_cost = 0 if cur_stair == -1 else cost[cur_stair]
            if cur_stair+1 in memo:
                cost1 = memo[cur_stair+1]
            else:
                cost1 = dfs(cur_stair+1)

            if cur_stair+2 in memo:
                cost2 = memo[cur_stair+2]
            else:
                cost2 = dfs(cur_stair+2)

            memo[cur_stair] = cur_cost+ min(cost1, cost2)
            return memo[cur_stair]
        return dfs(-1)

复杂度

Time: O(n)

Space: O(n)

zulliu commented 2 years ago

思路

使用动态规划,用数组记录min cost,手动设置0和1级初始阶梯,将当前层的min cost设置为前1级和前2级中最小的min cost + cost[i],返回数组中最后一位为最小cost。

代码

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

复杂度

时间:O(n) 空间:O(n)

user1689 commented 2 years ago

题目

https://leetcode-cn.com/problems/min-cost-climbing-stairs/

思路

DP

python3

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

        # dp[i]代表到达位置i的最小体力花费
        # dp[i] = min(dp[i - 1] + cost[i], dp[i - 2] + cost[i])

        n = len(cost)
        # 由于可以选择下标 0 或 1 作为初始阶梯,因此有 dp[0] = dp[1] = 0 
        dp = [0 for _ in range(n + 1)]
        for i in range(2, n + 1):
            dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])
        return dp[n]

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

        # dp[i]代表到达位置i的最小体力花费
        # dp[i] = min(dp[i - 1] + cost[i], dp[i - 2] + cost[i])

        n = len(cost)
        prev = cur = 0
        for i in range(2, n + 1):
            nxt = min(cur + cost[i - 1], prev + cost[i - 2])
            prev, cur = cur, nxt
        return nxt

复杂度分析

相关题目

  1. https://leetcode-cn.com/problems/climbing-stairs/
hellowxwworld commented 2 years ago

思路

动态规划 or 递归

代码

int minCostClimingStairs2(vector<int>& cost) {
    int n = cost.size();
    int dp[n+1];
    dp[0] = dp[1] = 0;

    for (int i = 2; i < n + 1; ++i) {
        dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]);
    }
    return dp[n];
}

int minCostClimingStairs(vector<int>& cost, int n) {
    if (n == 0 || n == 1) {
        return 0;
    }
    return min(minCostClimingStairs(cost, n-1) + cost[n-1], minCostClimingStairs(cost, n-2) + cost[n-2]);
}
shibingchao123 commented 2 years ago

思路 dp[i] = min(dp[i-1]+cost[i-1],p[i-2]+cost[i-2])

代码 func minCostClimbingStairs(cost []int) int { dp :=make([]int,len(cost)+1) dp[0] = 0 dp[1] = 0 for i:=2;i<len(dp);i++ { if dp[i-1]+cost[i-1]>dp[i-2]+cost[i-2] { dp[i]= dp[i-2]+cost[i-2] }else{ dp[i]= dp[i-1]+cost[i-1] } } return dp[len(cost)] } 复杂度分析 时间复杂度:O(n) 空间复杂度:O(n)

yyangeee commented 2 years ago
class Solution2:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        a,b = cost[0],cost[1]
        for i in range(2,(len(cost)+1)):
            c = min(a, b) + (cost[i] if i !=len(cost) else 0)
            a = b
            b = c
        return c

复杂度

Bochengwan commented 2 years ago

思路

dp1表示退一步的最小cost,dp2表示退两步的最小cost,每次取最小的cost+当前的cost。

代码

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

复杂度分析

JK1452470209 commented 2 years ago

思路

dp

代码

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        if (cost == null || cost.length == 0){
            return 0;
        }
        int dp[] = new int[cost.length + 1];
        dp[0] = cost[0];
        dp[1] = cost[1];
        for (int i = 2; i <= cost.length; i++) {
            if (i == cost.length) {
                dp[i] = Math.min(dp[i - 1], dp[i - 2]);
            } else{
                dp[i] = cost[i] + Math.min(dp[i - 1], dp[i - 2]);
            }
        }
        return dp[cost.length];
    }
}

复杂度

时间复杂度:O(N)

空间复杂度:O(N)

kennyxcao commented 2 years ago

746. Min Cost Climbing Stairs

Intuition

Code

/**
 * @param {number[]} cost
 * @return {number}
 */
const minCostClimbingStairs = function(cost) {
  let twoStepBefore = cost[0];
  let oneStepBefore = cost[1];
  let curr = 0;
  for (let i = 2; i < cost.length; i++) {
    curr = Math.min(twoStepBefore, oneStepBefore) + cost[i];
    twoStepBefore = oneStepBefore;
    oneStepBefore = curr;
  }
  return Math.min(twoStepBefore, oneStepBefore);
};

Complexity Analysis

RonghuanYou commented 2 years ago
class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:   
        for i in range(2, len(cost)):
            cost[i] += min(cost[i - 1], cost[i - 2])
        return min(cost[-2], cost[-1])
asterqian commented 2 years ago

思路

dp,可以从0或者1的位置开始都可以,所以0和1的memo值都为0。从index3开始,memo记录下从这一格往后走的cost是多少,即为前一格的memo值加上他的cost和前两格的memo值加上他的cost取最小值(either从前一格来或者从前两格来)。最后一个就是答案,因为我们initialize的是size + 1,就是到top的步数。

代码

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        vector<int> memo(cost.size() + 1, 0);
        for (int i = 2; i < cost.size() + 1; ++i) {
            memo[i] = min(memo[i - 1] + cost[i - 1], memo[i - 2] + cost[i - 2]);
        }
        return memo.back();
    }
};

Time Complexity: O(n)

Space Complexity: O(n)

asaoba commented 2 years ago

前置知识

公司

思路

动态规划问题

定义数组dp,dp[i]代表爬到第i级阶梯的最小花费,有题目可知dp[0]=dp[1]=0;

爬到第i级所需花费=爬到第(i-1)级阶梯的最小花费+第(i-1)级阶梯的花费/爬到第(i-2)级阶梯的最小花费+第(i-2)级阶梯的花费

取二者中的最小值,即:

dp[i]=Math.min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2])

关键点

代码

Java Code:


class Solution {
    //注意:要准确理解题意,观察用例
    //思路:动态规划
    public int minCostClimbingStairs(int[] cost) {
        int n=cost.length;
        int[] dp=new int[n+1];//dp[i]代表到达第i级阶梯的最小花费
        dp[0]=0;
        dp[1]=0;
        for(int i=2;i<=n;i++){
            dp[i]=Math.min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
        }
        return dp[n];
    }
}

复杂度分析

令 n 为数组长度。

july-aha commented 2 years ago
var minCostClimbingStairs = function(cost) {
    let p=q=0,temp;
    for(let i=2;i<=cost.length;i++){
        temp = q
        q=Math.min(p+cost[i-2],q+cost[i-1]);
        p = temp;
    }
    return q;
};