返回介绍

solution / 0700-0799 / 0746.Min Cost Climbing Stairs / README

发布于 2024-06-17 01:03:34 字数 5339 浏览 0 评论 0 收藏 0

746. 使用最小花费爬楼梯

English Version

题目描述

给你一个整数数组 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 。

 

提示:

  • 2 <= cost.length <= 1000
  • 0 <= cost[i] <= 999

解法

方法一:动态规划

我们定义 $f[i]$ 表示到达第 $i$ 个阶梯所需要的最小花费,初始时 $f[0] = f[1] = 0$,答案即为 $f[n]$。

当 $i \ge 2$ 时,我们可以从第 $i - 1$ 个阶梯使用 $1$ 步直接到达第 $i$ 个阶梯,或者从第 $i - 2$ 个阶梯使用 $2$ 步到达第 $i$ 个阶梯,因此我们有状态转移方程:

$$ f[i] = \min(f[i - 1] + cost[i - 1], f[i - 2] + cost[i - 2]) $$

最终的答案即为 $f[n]$。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 cost 的长度。

我们注意到,状态转移方程中的 $f[i]$ 只和 $f[i - 1]$ 与 $f[i - 2]$ 有关,因此我们可以使用两个变量 $f$ 和 $g$ 交替地记录 $f[i - 2]$ 和 $f[i - 1]$ 的值,这样空间复杂度可以优化到 $O(1)$。

class Solution:
  def minCostClimbingStairs(self, cost: List[int]) -> int:
    n = len(cost)
    f = [0] * (n + 1)
    for i in range(2, n + 1):
      f[i] = min(f[i - 2] + cost[i - 2], f[i - 1] + cost[i - 1])
    return f[n]
class Solution {
  public int minCostClimbingStairs(int[] cost) {
    int n = cost.length;
    int[] f = new int[n + 1];
    for (int i = 2; i <= n; ++i) {
      f[i] = Math.min(f[i - 2] + cost[i - 2], f[i - 1] + cost[i - 1]);
    }
    return f[n];
  }
}
class Solution {
public:
  int minCostClimbingStairs(vector<int>& cost) {
    int n = cost.size();
    vector<int> f(n + 1);
    for (int i = 2; i <= n; ++i) {
      f[i] = min(f[i - 2] + cost[i - 2], f[i - 1] + cost[i - 1]);
    }
    return f[n];
  }
};
func minCostClimbingStairs(cost []int) int {
  n := len(cost)
  f := make([]int, n+1)
  for i := 2; i <= n; i++ {
    f[i] = min(f[i-1]+cost[i-1], f[i-2]+cost[i-2])
  }
  return f[n]
}
function minCostClimbingStairs(cost: number[]): number {
  const n = cost.length;
  const f: number[] = Array(n + 1).fill(0);
  for (let i = 2; i <= n; ++i) {
    f[i] = Math.min(f[i - 1] + cost[i - 1], f[i - 2] + cost[i - 2]);
  }
  return f[n];
}
impl Solution {
  pub fn min_cost_climbing_stairs(cost: Vec<i32>) -> i32 {
    let n = cost.len();
    let mut f = vec![0; n + 1];
    for i in 2..=n {
      f[i] = std::cmp::min(f[i - 2] + cost[i - 2], f[i - 1] + cost[i - 1]);
    }
    f[n]
  }
}

方法二

class Solution:
  def minCostClimbingStairs(self, cost: List[int]) -> int:
    f = g = 0
    for i in range(2, len(cost) + 1):
      f, g = g, min(f + cost[i - 2], g + cost[i - 1])
    return g
class Solution {
  public int minCostClimbingStairs(int[] cost) {
    int f = 0, g = 0;
    for (int i = 2; i <= cost.length; ++i) {
      int gg = Math.min(f + cost[i - 2], g + cost[i - 1]);
      f = g;
      g = gg;
    }
    return g;
  }
}
class Solution {
public:
  int minCostClimbingStairs(vector<int>& cost) {
    int f = 0, g = 0;
    for (int i = 2; i <= cost.size(); ++i) {
      int gg = min(f + cost[i - 2], g + cost[i - 1]);
      f = g;
      g = gg;
    }
    return g;
  }
};
func minCostClimbingStairs(cost []int) int {
  var f, g int
  for i := 2; i <= n; i++ {
    f, g = g, min(f+cost[i-2], g+cost[i-1])
  }
  return g
}
function minCostClimbingStairs(cost: number[]): number {
  let a = 0,
    b = 0;
  for (let i = 1; i < cost.length; ++i) {
    [a, b] = [b, Math.min(a + cost[i - 1], b + cost[i])];
  }
  return b;
}
impl Solution {
  pub fn min_cost_climbing_stairs(cost: Vec<i32>) -> i32 {
    let (mut f, mut g) = (0, 0);
    for i in 2..=cost.len() {
      let gg = std::cmp::min(f + cost[i - 2], g + cost[i - 1]);
      f = g;
      g = gg;
    }
    g
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文