爬楼梯_70_746
LeetCode_70原题链接:https://leetcode-cn.com/problems/climbing-stairs/
题目描述:
假设你正在爬楼梯。需要 n
阶你才能到达楼顶。
每次你可以爬 1
或 2
个台阶。你有多少种不同的方法可以爬到楼顶呢?
动态规划: 1.本问题可以分成多个子问题,爬第n阶楼梯的方法数量,等于 2 部分之和。 2.爬上 n−1 阶楼梯的方法数量。因为再爬1阶就能到第n阶 3.爬上 n−2 阶楼梯的方法数量,因为再爬2阶就能到第n阶 4.所以我们得到公式 dp[n] = dp[n-1] + dp[n-2] 同时需要初始化 dp[0]=1 和 dp[1]=1 时间复杂度:O(n) 其中dp[n],表示爬上该楼梯的可能性。 dp[0],爬上0层,可能走法初始为1种 dp[1], 爬上1层,可能走法为1种 dp[2], 爬上2层,则可能的走法为2种,dp[0]+dp[1]. dp[3], 爬上3层,则可能的走法有dp[2]+dp[1]加起来。 class Solution { public int climbStairs(int n) { int[] dp = new int[n + 1]; dp[0] = 1; dp[1] = 1; for(int i = 2; i <= n; i++) { dp[i] = dp[i - 1] + dp[i - 2]; } return dp[n]; } } class Solution { public int climbStairs(int n) { int[] memo = new int[n+1]; return climbStairsMemo(n, memo); } public int climbStairsMemo(int n, int[] memo) { if(memo[n] > 0) { return memo[n]; } if(n == 1) { memo[n] = 1; } else if (n == 2) { memo[n] = 2; } else { memo[n] = climbStairsMemo(n-1, memo) + climbStairsMemo(n-2, memo); } return memo[n]; } }
跳台阶扩展问题:https://www.nowcoder.com/practice/22243d016f6b47f2a6928b4313c85387
题目描述:
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶(n为正整数)总共有多少种跳法。
1.当n = n时,Fiber(n)= Fib(n-1) + Fib(n-2) + ....Fib(0); 2.当n = n-1时,Fiber(n-1)= Fib(n-2) + Fib(n-3)......Fib(0); 两者相减,Fiber(n)= 2 * Fiber(n-1); public class Solution { public int JumpFloorII(int target) { if(target <= 1){ return 1; } return 2 * JumpFloorII(target-1); } public int jumpFloorII(int target) { if(target < 2) { return 1; } return (int) Math.pow(2,target-1); } public int jumpFloorII(int target) { if(target==0 || target==1) { return 1; } int a = 1, b = 0; for (int i=2; i<=target; i++){ b = a<<1; a = b; } return b; } }
LeetCode_746原题链接:https://leetcode-cn.com/problems/min-cost-climbing-stairs/
题目描述:
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
动态规划: 1.假设数组 cost 的长度为 n, 则 n 个阶梯分别对应下标 0 到 n−1,楼层顶部对应下标 n,问题等价于计算达到下标n 的最小花费。 2.创建长度为 n+1 的数组 dp,其中 dp[i] 表示达到下标 i 的最小花费。 3.由于可以选择下标 0 或 1 作为初始阶梯,因此有 dp[0] = dp[1] = 0。 4.当 2≤i≤n 时, 可以从下标 i−1 使用 cost[i−1] 的花费达到下标 i, 或者从下标 i−2 使用 cost[i−2] 的花费达到下标 i。 5.为了使总花费最小,dp[i] 应取上述两项的最小值, 因此状态转移方程如下: dp[i]=min(dp[i−1]+cost[i−1], dp[i−2]+cost[i−2]) 6.依次计算 dp 中的每一项的值,最终得到的 dp[n] 即为达到楼层顶部的最小花费。 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)。 注意到当 i≥2 时,dp[i] 只和 dp[i−1] 与 dp[i−2] 有关, 因此可以使用滚动数组的思想,将空间复杂度优化到 O(1)。 class Solution { public int minCostClimbingStairs(int[] cost) { int n = cost.length; 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),其中 n 是数组 cost 的长度。 需要依次计算每个 }dp 值,每个值的计算需要常数时间,因此总时间复杂度是 )O(n)。 空间复杂度:O(1)。使用滚动数组的思想,只需要使用有限的额外空间。
------------恢复内容结束------------
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】