力扣刷题记录——爬楼梯和最小花费爬楼梯

今天新开了一个专栏,打算把平时整理的一些力扣刷的题写一写......佛系更新,佛系布局。

本文2道题都是关于动态规划思想的,思路也相近,所以做一个整理。

目录

爬楼梯

思路

代码

最小花费爬楼梯

思路

代码

 


爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 12 个台阶。你有多少种不同的方法可以爬到楼顶呢?

示例1:

输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。

1. 1 阶 + 1 阶
2. 2 阶

示例2:

输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。

1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶

思路

我的思路是这样的:设想出发点为第0阶,一共有n阶。那么建立长度为n+1的数组res,记录从第0-n阶到达第n阶的方法数。显然res的最后三位分别是2、1、0,然后向前遍历。在第x阶出发,要么走一阶到达第x+1阶,然后就有res[x+1]种方法;要么走2阶到达第x+2阶,然后就有res[x+3]阶。依次向前,计算得到res[0]就是从原点出发可能的方法数。

代码

class Solution {
    public int climbStairs(int n) {
        if(n<=3){
            return n;
        }
        // 记录从该台阶出发到达第n阶的方法数
        // 0 - n代表0阶 - n阶
        int[] res=new int[n+1];
        res[n]=0;
        res[n-1]=1;
        res[n-2]=2;
        for(int i=n-3;i>=0;i--){
            res[i]=res[i+1]+res[i+2];
        }
        return res[0];
    }
}

最小花费爬楼梯

给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。

你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。

请你计算并返回达到楼梯顶部的最低花费。

示例1:

输入:cost = [10,15,20]
输出:15
解释:你将从下标为 1 的台阶开始。

- 支付 15 ,向上爬两个台阶,到达楼梯顶部。
  总花费为 15 。

示例2:

`输入:cost = [1,100,1,1,1,100,1,1,100,1]`
`输出:6`
`解释:你将从下标为 0 的台阶开始。`

- `支付 1 ,向上爬两个台阶,到达下标为 2 的台阶。`
- `支付 1 ,向上爬两个台阶,到达下标为 4 的台阶。`
- `支付 1 ,向上爬两个台阶,到达下标为 6 的台阶。`
- `支付 1 ,向上爬一个台阶,到达下标为 7 的台阶。`
- `支付 1 ,向上爬两个台阶,到达下标为 9 的台阶。`
- `支付 1 ,向上爬一个台阶,到达楼梯顶部。`
  `总花费为 6 。`

思路

这道题与上一道题很类似,但也有区别。主要体现在,上一道题一定是从第0阶(第1阶之前)到第n阶;本题是,可以从下标为0或1的台阶出发,最终到达最高。注意,本题中,只要脚踩某个台阶,花费中就要包含它。例如,从下标为n-2的阶经过下标为n-1的阶到达终点,相当于踩了n-2、n-1,因此花费是cost[n-2]+cost[n-1];从下标为n-2的阶直接到达终点,相当于踩了n-2,跨过了n-1,因此花费是cost[n-2]。且从任意一阶出发,费用一定包含出发阶的花费。

其余的思路就差不多了。从后往前遍历,计算从该阶出发的最小花费,最终得到从下标为0和1的阶出发的最小花费,取最小值即可。

代码

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n=cost.length;
        if(n==1){
            return cost[0];
        }
        if(n==2){
            return cost[0]<cost[1]?cost[0]:cost[1];
        }
        // 记录从第i阶开始的最小花费
        // 从下标为0的台阶到下标为n-1的台阶
        // 只要经过该台阶,花费中就包含它
        int[] minLs=new int[n];
        minLs[n-1]=cost[n-1];
        minLs[n-2]=cost[n-2];
        for(int i=n-3;i>=0;i--){
            minLs[i]=(cost[i]+minLs[i+1])<(cost[i]+minLs[i+2])?(cost[i]+minLs[i+1]):(cost[i]+minLs[i+2]);
        }
        return minLs[0]<minLs[1]?minLs[0]:minLs[1];
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值