LeetCode - Easy - 70. Climbing Stairs

深藏阁楼爱情的钟 2022-12-28 00:40 217阅读 0赞

Topic

Dynamic Programming

Description

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

You are climbing a staircase. It takes n steps to reach the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

Example 1:

  1. Input: n = 2
  2. Output: 2
  3. Explanation: There are two ways to climb to the top.
  4. 1. 1 step + 1 step
  5. 2. 2 steps

Example 2:

  1. Input: n = 3
  2. Output: 3
  3. Explanation: There are three ways to climb to the top.
  4. 1. 1 step + 1 step + 1 step
  5. 2. 1 step + 2 steps
  6. 3. 2 steps + 1 step

Constraints:

  • 1 <= n <= 45

Analysis

逐步分析,找出其中的规律。设f(n)为在n个阶梯上,每步1或2个阶梯,则有多少种方式登上顶。

由题目得f(1)=1,f(2)=2,f(3)=3。


n = 4,则有以下方案

  1. 1 + 1 + 1 + 1
  2. 1 + 1 + 2
  3. 1 + 2 + 1
  4. 2 + 1 + 1
  5. 2 + 2

总共有5种方案,观察其中规律:当第1步走1个阶梯,剩下有f(3)=3种走法(13加粗的部分),当第1步走2个阶梯,剩下有f(2)=2种走法(45加粗的部分)。

可得f(4)=f(3)+f(2)。那么,大胆推测一下,f(n) = f(n-1) + f(n-2)。我们再举n=5实证一下。


n = 5,则有以下方案

  1. 1 + 1 + 1 + 1 + 1
  2. 1 + 1 + 1 + 2
  3. 1 + 1 + 2 + 1
  4. 1 + 2 + 1 + 1
  5. 1 + 2 + 2
  6. 2 + 1 + 1 + 1
  7. 2 + 1 + 2
  8. 2 + 2 + 1

总共有8种方案,观察其中规律:当第1步走1个阶梯,剩下有f(4)=5种走法(15加粗的部分),当第1步走2个阶梯,剩下有f(3)=3种走法(68加粗的部分)。可得f(5)=f(4)+f(3)

因此,表达式f(n) = f(n-1) + f(n-2) 应该就是解决这题目的关键。

f(n) = f(n-1) + f(n-2),这不就是斐波那契数列,当初学递归时接触的经典数列。

代码实现方法:

  • 方法一:递归法,另分配数组作缓存
  • 方法二:迭代法
  • 方法三:尾递归法

Submission

  1. public class ClimbingStairs {
  2. //方法二:
  3. public int climbStairs1(int n) {
  4. if (n == 1 || n == 2)
  5. return n;
  6. int first = 1, second = 2;
  7. for (int i = 2; i < n; i++) {
  8. int temp = first + second;
  9. first = second;
  10. second = temp;
  11. }
  12. return second;
  13. }
  14. //方法三:
  15. public int climbStairs2(int n) {
  16. if (n == 1)
  17. return 1;
  18. return climbStairs2(1, 2, n, 2);
  19. }
  20. private int climbStairs2(int first, int second, int num, int index) {
  21. return index == num ? second : climbStairs2(second, first + second, num, index + 1);
  22. }
  23. //方法二:别人写的
  24. public int climbStairs3(int n) {
  25. int a = 1, b = 1;
  26. while (n-- > 0)
  27. a = (b += a) - a;
  28. return a;
  29. }
  30. }

Test

  1. import static org.junit.Assert.*;
  2. import org.junit.Test;
  3. public class ClimbingStairsTest {
  4. @Test
  5. public void test() {
  6. ClimbingStairs obj = new ClimbingStairs();
  7. assertEquals(1, obj.climbStairs1(1));
  8. assertEquals(2, obj.climbStairs1(2));
  9. assertEquals(3, obj.climbStairs1(3));
  10. assertEquals(5, obj.climbStairs1(4));
  11. assertEquals(8, obj.climbStairs1(5));
  12. assertEquals(1, obj.climbStairs2(1));
  13. assertEquals(2, obj.climbStairs2(2));
  14. assertEquals(3, obj.climbStairs2(3));
  15. assertEquals(5, obj.climbStairs2(4));
  16. assertEquals(8, obj.climbStairs2(5));
  17. for(int i = 1; i <= 100; i++) {
  18. assertEquals(obj.climbStairs1(i), obj.climbStairs2(i));
  19. assertEquals(obj.climbStairs1(i), obj.climbStairs3(i));
  20. }
  21. }
  22. }

发表评论

表情:
评论列表 (有 0 条评论,217人围观)

还没有评论,来说两句吧...

相关阅读