2026-02-21:爬楼梯Ⅱ。用go语言,你要爬一段共有 n+1 级的台阶,编号从 0 到 n。给定一个长度为 n、下标从 1 开始的数组 costs,其中

0 阅读5分钟

2026-02-21:爬楼梯Ⅱ。用go语言,你要爬一段共有 n+1 级的台阶,编号从 0 到 n。给定一个长度为 n、下标从 1 开始的数组 costs,其中 costs[i] 表示第 i 级台阶自身的费用(第 0 级没有对应的 costs 项)。

每一步可以从当前台阶 i 向前跳到 i+1、i+2 或 i+3 中的任一台阶,若从 i 跳到 j,则这次移动会增加 costs[j] 与跳跃距离的平方之和作为代价,即增加 costs[j] + (j − i)^2。初始位于台阶 0,累计费用从 0 开始。

返回到达台阶 n 时可能得到的最小累计费用。

1 <= n == costs.length <= 100000。

1 <= costs[i] <= 10000。

输入:n = 4, costs = [1,2,3,4]。

输出:13。

解释:

一个最优路径是 0 → 1 → 2 → 4。

跳跃成本计算成本
0 → 1costs[1] + (1 - 0)^2 = 1 + 12
1 → 2costs[2] + (2 - 1)^2 = 2 + 13
2 → 4costs[4] + (4 - 2)^2 = 4 + 48

因此,最小总成本为 2 + 3 + 8 = 13。

题目来自力扣3693。


问题理解

  • n+1 级台阶,编号 0n
  • 数组 costs 长度是 n,下标从 1 开始,costs[i] 表示第 i 级台阶的费用。
  • 0 级没有费用。
  • 从台阶 i 可以跳到 i+1i+2i+3
  • i 跳到 j 的成本 = costs[j] + (j - i)^2
  • 0 出发,累计费用初始为 0
  • 要到达台阶 n,求最小累计费用。

例子说明

题目给的例子:

  • n = 4, costs = [1,2,3,4]
  • 路径:0 → 1 → 2 → 4
    • 0 → 1: costs[1] + 1² = 1 + 1 = 2
    • 1 → 2: costs[2] + 1² = 2 + 1 = 3
    • 2 → 4: costs[4] + 2² = 4 + 4 = 8
  • 总成本 = 2 + 3 + 8 = 13

代码逻辑分析(逐步推理)

1. 初始化

  • f0 表示到达台阶 0 的最小费用,即 f0 = 0
  • 如果 n == 0,直接返回 f0

2. 到达台阶 1

  • 01 只有一种跳法(距离 1)。
  • 成本 = costs[1] + 1(因为 (1-0)² = 1)。
  • 所以 f1 = costs[0] + 1 + f0
  • 如果 n == 1,返回 f1

3. 到达台阶 2

有两种可能:

  • 0 直接跳到 2(距离 2):
    • 成本 = costs[2] + 4 + f0
  • 1 跳到 2(距离 1):
    • 成本 = costs[2] + 1 + f1

代码中比较这两者,取最小值:

if costs[1] + f1 + 1 < costs[1] + f0 + 4:
    f2 = costs[1] + f1 + 1
else:
    f2 = costs[1] + f0 + 4

注意这里 costs[1]costs[2](因为下标从 1 开始),所以这其实是:

  • costs[2] + f1 + 1(从 1 跳过来)
  • costs[2] + f0 + 4(从 0 跳过来)

4. 到达台阶 i ≥ 3

i-3i-2i-1 都可以跳到 i

  • i-3 跳过来:距离 3,成本 = f(i-3) + costs[i] + 9
  • i-2 跳过来:距离 2,成本 = f(i-2) + costs[i] + 4
  • i-1 跳过来:距离 1,成本 = f(i-1) + costs[i] + 1

取三者最小值:

f = min(f0 + 9 + costs[i-1], f1 + 4 + costs[i-1], f2 + 1 + costs[i-1])

这里的 f0 其实是 f(i-3)f1f(i-2)f2f(i-1)

更新 f0f1f2 为下一轮的状态。


算法流程总结

  1. 如果 n == 0,直接返回 0。
  2. 如果 n == 1,返回 costs[1] + 1
  3. 如果 n == 2,返回 min(costs[2] + f1 + 1, costs[2] + f0 + 4)
  4. i = 3n
    • 计算到达 i 的最小费用:
      • i-3 来:f0 + 9 + costs[i-1]
      • i-2 来:f1 + 4 + costs[i-1]
      • i-1 来:f2 + 1 + costs[i-1]
    • 取最小值作为 f
    • 更新 f0 = f1f1 = f2f2 = f
  5. 返回 f2,即到达台阶 n 的最小费用。

时间复杂度和空间复杂度

  • 时间复杂度:我们只遍历了从 i=0n 一次,每一步做常数次比较和计算,所以是 O(n)
  • 额外空间复杂度:只用了三个变量 f0f1f2 来记录状态,没有用数组存储所有结果,所以是 O(1)

最终答案

  • 时间复杂度:O(n)
  • 额外空间复杂度:O(1)

Go完整代码如下:

package main

import (
	"fmt"
)

func minNew(a, b, c int) int {
	if a <= b && a <= c {
		return a
	} else if b <= a && b <= c {
		return b
	}
	return c
}

func climbStairs(n int, costs []int) int {
	var f0, f1, f2 int
	f0 = 0
	if n == 0 {
		return f0
	}
	f1 = costs[0] + 1 + f0
	if n == 1 {
		return f1
	}
	// min(costs[1] + f1 + 1, costs[1] + f0 + 4)
	if costs[1]+f1+1 < costs[1]+f0+4 {
		f2 = costs[1] + f1 + 1
	} else {
		f2 = costs[1] + f0 + 4
	}
	if n == 2 {
		return f2
	}
	for i := 3; i <= n; i++ {
		f := minNew(f0+9+costs[i-1], f1+4+costs[i-1], f2+1+costs[i-1])
		f0 = f1
		f1 = f2
		f2 = f
	}
	return f2
}

func main() {
	n := 4
	costs := []int{1, 2, 3, 4}
	result := climbStairs(n, costs)
	fmt.Println(result)
}

在这里插入图片描述

Python完整代码如下:

# -*-coding:utf-8-*-

def min_new(a, b, c):
    if a <= b and a <= c:
        return a
    elif b <= a and b <= c:
        return b
    return c

def climbStairs(n, costs):
    f0 = 0
    if n == 0:
        return f0
    
    f1 = costs[0] + 1 + f0
    if n == 1:
        return f1
    
    # min(costs[1] + f1 + 1, costs[1] + f0 + 4)
    if costs[1] + f1 + 1 < costs[1] + f0 + 4:
        f2 = costs[1] + f1 + 1
    else:
        f2 = costs[1] + f0 + 4
    
    if n == 2:
        return f2
    
    for i in range(3, n + 1):
        f = min_new(f0 + 9 + costs[i - 1], 
                    f1 + 4 + costs[i - 1], 
                    f2 + 1 + costs[i - 1])
        f0 = f1
        f1 = f2
        f2 = f
    
    return f2

def main():
    n = 4
    costs = [1, 2, 3, 4]
    result = climbStairs(n, costs)
    print(result)  

if __name__ == "__main__":
    main()

在这里插入图片描述

C++完整代码如下:

#include <iostream>
#include <vector>
using namespace std;

int min_new(int a, int b, int c) {
    if (a <= b && a <= c) {
        return a;
    } else if (b <= a && b <= c) {
        return b;
    }
    return c;
}

int climbStairs(int n, vector<int>& costs) {
    int f0, f1, f2;
    f0 = 0;

    if (n == 0) {
        return f0;
    }

    f1 = costs[0] + 1 + f0;
    if (n == 1) {
        return f1;
    }

    // min(costs[1] + f1 + 1, costs[1] + f0 + 4)
    if (costs[1] + f1 + 1 < costs[1] + f0 + 4) {
        f2 = costs[1] + f1 + 1;
    } else {
        f2 = costs[1] + f0 + 4;
    }

    if (n == 2) {
        return f2;
    }

    for (int i = 3; i <= n; i++) {
        int f = min_new(f0 + 9 + costs[i - 1],
                        f1 + 4 + costs[i - 1],
                        f2 + 1 + costs[i - 1]);
        f0 = f1;
        f1 = f2;
        f2 = f;
    }

    return f2;
}

int main() {
    int n = 4;
    vector<int> costs = {1, 2, 3, 4};
    int result = climbStairs(n, costs);
    cout << result << endl;
    return 0;
}

在这里插入图片描述