• 爬楼梯


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

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

    注意:给定 n 是一个正整数。

    示例 1:

    输入: 2
    输出: 2
    解释: 有两种方法可以爬到楼顶。
    1.  1 阶 + 1 阶
    2.  2 阶
    

    示例 2:

    输入: 3
    输出: 3
    解释: 有三种方法可以爬到楼顶。
    1.  1 阶 + 1 阶 + 1 阶
    2.  1 阶 + 2 阶
    3.  2 阶 + 1 阶
    

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/climbing-stairs
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    解题:

    解法参考自力扣(LeetCode)

    解法1 暴力硬解

    在某一阶楼梯上,下一步有两种走法:走1阶或者走2阶,如此反复,生成一棵递归树,则可以计算出所有方法的总数。

    package climbing.stairs;
    
    class Solution {
        /**
         * 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
         * 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
         * 注意:给定 n 是一个正整数。
         * @param n 到达楼顶的阶数n
         * @return 到达楼顶的方法总数
         */
        public int climbStairs(int n) {
            return climb(0, n);
        }
    
        /**
         * 递归暴力硬解
         * @param nNow 当前所在的阶梯数
         * @param n 总阶梯数
         * @return 当前阶梯到楼顶的爬楼梯方法总数
         */
        public int climb(int nNow, int n) {
            // 如果这一步之后当前阶数大于总阶数,由于最多跨出2阶,说明在迈出这一步之前处于n-1阶,此时只能走1阶,则跨出2阶是错误的,该步不计入总数
            if (nNow > n) {
                return 0;
            }
            // 如果这一步之后当前阶数等于总阶数,说明在迈出这一步之前处于n-1阶,此时只能走1步
            if (nNow == n) {
                return 1;
            }
    
            // 在处于某一阶时,可以有两种走法,一种是到达下1阶,一种是到达下2阶。
            return climb(nNow+1, n) + climb(nNow+2, n);
        }
    }
    
    

    可以预见,这样的解法消耗的时间是巨额的,果不其然,提交到leetCode的结果是超时:

    image-20200609170737868

    解法2 斐波那契数列

    反向来想,到达第i阶的方法有两种:在第i-1阶跨1阶到达,或者在第i-2阶跨2阶到达。设到达第i阶的方法为counter[i],则counter[i]=counter[i-1]+counter[i-2],则该题就变成了一道解斐波那契数列的题目,该数列的第一个数为1,第二个数为2。

    package climbing.stairs;
    
    /**
     * @author focksor
     */
    public class Solution {
        /**
         * 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
         * 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
         * 注意:给定 n 是一个正整数。
         * @param n 到达楼顶的阶数n
         * @return 到达楼顶的方法总数
         */
        public int climbStairs(int n) {
            if (n < 2) {
                return n;
            }
            int a = 1;
            int b = 2;
            for (int i = 2; i < n; i++) {
                if (a >= b) {
                    b += a;
                } else {
                    a += b;
                }
            }
    
            return a>=b?a:b;
        }
    }
    
    

    结果:

    image-20200609180458010

    本地测试代码

    package climbing.stairs;
    
    import org.junit.Assert;
    import org.junit.Test;
    
    /**
     * @author focksor
     *
     * 示例 1:
     * 输入: 2
     * 输出: 2
     * 解释: 有两种方法可以爬到楼顶。
     * 1.  1 阶 + 1 阶
     * 2.  2 阶
     *
     * 示例 2:
     * 输入: 3
     * 输出: 3
     * 解释: 有三种方法可以爬到楼顶。
     * 1.  1 阶 + 1 阶 + 1 阶
     * 2.  1 阶 + 2 阶
     * 3.  2 阶 + 1 阶
     *
     * 来源:力扣(LeetCode)
     * 链接:https://leetcode-cn.com/problems/climbing-stairs
     * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
     */
    public class SolutionTest {
        @Test
        public void test() {
            check(1, 1);
            check(2, 2);
            check(3, 3);
            check(4, 5);
            check(5, 8);
    
        }
    
        public void check(int n, int result) {
            Solution solution = new Solution();
            int solutionRes = solution.climbStairs(n);
    
            Assert.assertEquals(result, solutionRes);
        }
    }
    
  • 相关阅读:
    java8 Stream排序字段为空排序方法
    SpringBoot使用token简单鉴权的具体实现方法
    性能调优
    TestNG最简单的测试
    TestNG异常测试
    TestNG中如何执行测试
    TestNG的基本注解
    TestNG介绍
    TestNG 环境搭建
    python第四课笔记
  • 原文地址:https://www.cnblogs.com/focksor/p/climbing-stairs.html
Copyright © 2020-2023  润新知