LeetCode——第70题:爬楼梯

题目:

假设你正在爬楼梯。需要 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 步

代码:

/**
 * @作者:dhc
 * @创建时间:11:06 2018/8/8
 * @描述:爬楼梯
 */
public class Seventy {
    //错误思路
    //3ms,刷题的时候因为分类是动态规划,自然就往这面想,首先想最优子结构,
    // 《《《这题求爬n阶楼梯,每次一步或者两步,n阶的爬楼梯的最高次数,那么n-m和m
    //阶的楼梯的爬法的次数也应该是最多的,没啥问题,但是有个问题就是除了n-m
    //加上m阶爬的方法的次数之外,还应该加上从划分的m阶楼梯到后面n-m接楼梯的爬法
    // 对于m和n-m都大于2阶,有三种(从m到m+1,从m-1到m+1,从m到m+2),但是如果某一部分
    // 只有一阶,则只有2中,如果两个都是1阶,即n=2,还是个特殊情况;》》》然后想的就是
    //重复子问题,很明显,m阶和n-m阶中肯定存在重复子问题。然后就是自底向上的算,
    //n=1,2...,。其实这是在写完后想的,并且没想明白,应该是这种最右子结构思路是错的,特此记录。

    //因为分类是动态规划,就想到最优子结构性质和重复子问题,对于最右子结构想的不是很明白
    //但是一想n阶的最多爬法必然包含其子问题的最多爬法应该没毛病,然后重复子问题也没啥毛病
    //然后就是想看一下前面的几阶的值,想找下规律,(开始想的是result(n) = result(n-1)+2+result(n-2)+2,后来验证错误)
    //求了前几个然后找出了result(n)=result(n-1)+result(n-2),而
    // 这也符合重复子问题和最优子结构性质,所以。。代码如下,看了下其他人大多都是这个写法
    public int climbStairs2(int n) {
        int[] nums =  new int[n+2];
        if(n == 0){
            return 0;
        }
        nums[1] = 1;
        nums[2] = 2;
        for(int i = 3;i <= n;i++){
            nums[i] = nums[i-1] + nums[i-2];
        }
        return nums[n];
    }
    //2ms范例(这个用递归,感觉自顶向下有点像备忘录方法,但是递归到最后是从子问题n=1开始求,所以是动态规划)
    public int climbStairs(int n) {
        int[] memo = new int[n + 1];
        for (int i = 0; i < n + 1; i++) {
            memo[i] = -1;
        }
        return help(n,memo);
    }
    private int help(int n,int[] memo){
        if (n==1 || n==0)
            return 1;
        if (memo[n] == -1){
            memo[n] = help(n-1,memo)+help(n-2,memo);
        }
        return memo[n];
    }
}

你可能感兴趣的:(java,算法,leetCode)