zoukankan      html  css  js  c++  java
  • 70. Climbing Stairs

    题目:

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

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

    链接: http://leetcode.com/problems/climbing-stairs/

    题解:

    费波纳茨序列,使用Dynamic Programming,先构建一个一维数组。Time Complexity - O(n), Space Complexity - O(n)。

    public class Solution {
        public int climbStairs(int n) {
            int[] result = new int[n + 1];
            result[0] = 1;
            result[1] = 1;
    for(int i = 2; i < n + 1; i ++){ result[i] = result[i - 1] + result[i - 2]; }
    return result[n]; } }

    可以继续优化空间复杂度,使用两个变量存储之前的值。 Time Complexity - O(n), Space Complexity - O(1)

    public class Solution {
        public int climbStairs(int n) {
            int result = 1, prevStep = 1, curStep = 1;
            
            for(int i = 2; i < n + 1; i ++){
                result = prevStep + curStep;
                prevStep = curStep;
                curStep = result;
            }
            
            return result;
        }
    }

    Update:  前几天BB的电面遇到这一题,不过是三个数,所以要用 first + second + third

    public class Solution {
        public int climbStairs(int n) {
            if(n < 2)
                return 1;
            int first = 1, second = 1, res = 0;
            
            for(int i = 2; i < n + 1; i++) {
                res = first + second;
                first = second;
                second = res;
            }
            
            return res;
        }
    }

     

    还可以继续优化 - 使用矩阵法计算Fib。 Time Complexity - O(logn),Space Complexity - O(1).

    http://www.gocalf.com/blog/calc-fibonacci.html 

    二刷:

    矩阵法确实比较快,在Dasgupta的Algorithms那本书里见到过,但还从来没试过怎么写。 所以还是用了dp。关于dp仍然要好好学习和练习,搞清楚应该如何思考。

    这里dp的时候,新建dp数组是new dp[n + 1], 为什么这里要加1呢? 我觉得主要就是节省边界条件的代码。也要看我们怎么定义,我们定义dp[i]是到第i步为止的总步数,那么dp[0]就是第0步为止,dp[1]就是第一步为止,dp[2] = dp[0] + dp[1]是第二步为止我们有多少方法。 那么最后dp[n]就是到第n步为止,那么数组总长度其实是 n + 1。这个跟其他dp,比如Edit Distance差不多,都要考虑一下初始状态,比如Edit Distance我们就要对两个字符串都为空时进行初始化,然后才能在遍历过程中套用转移方程。

    Java:

    Time Complexity - O(n), Space Complexity - O(1)

    public class Solution {
        public int climbStairs(int n) {
            if (n <= 0) {
                return 0;
            }
            if (n <= 2) {
                return n;
            }
            int climbOneStep = 2, climbTwoStep = 1;
            int curSteps = 0;
            
            for (int i = 3; i <= n; i++) {
                curSteps = climbOneStep + climbTwoStep;
                climbTwoStep = climbOneStep;
                climbOneStep = curSteps;
            }
            return curSteps;
        }
    }

    题外话:

    2/4/2016

    最近几天突然忙起来了。工作,健身,上课。看书学习以及做题的时间被很大程度压缩了。还是要好好搞一搞time management。很羡慕那些有精力又会管理时间的人。

    三刷:

    又回来考虑了为什么dp写不好,这是因为自己没有学好系统的方法。一般要分为几个步骤,

    1. 定义dp含义

    2. 初始化

    3. 转移方程

    还有,这些可以递归的题目,跟离散数学里的同质性方程和异质性方程的解都很有关系。没有学过离散数学,缺少系统级知识的支持,对我来说自然很难写好...多学多练吧。

    1d dp 

    Java:

    Time Complexity - O(n), Space Complexity - O(n)

    public class Solution {
        public int climbStairs(int n) {
            if (n < 0) {
                return 0;
            }
            int[] dp = new int[n + 1];
            dp[0] = 1;
            dp[1] = 1;
            
            for (int i = 2; i <= n; i++) {
                dp[i] = dp[i - 1] + dp[i - 2];
            }
            return dp[n];
        }
    }

    压缩空间复杂度:

    Time Complexity - O(n), Space Complexity - O(1)

    public class Solution {
        public int climbStairs(int n) {
            if (n < 0) {
                return 0;
            }
            int curSteps = 1;
            int oneStepBack = 1;
            int twoStepsBack = 1;
            
            for (int i = 2; i <= n; i++) {
                curSteps = oneStepBack + twoStepsBack;
                twoStepsBack = oneStepBack;
                oneStepBack = curSteps;
            }
            return curSteps;
        }
    }

     

    矩阵法:

    如何证明还不确定,但主要是利用一个公式。 f(0) = 1, f(1) = 1, 这样我们就可以快速求出 在 n >= 1情况下, f(n + 1)的值。 

    [f(n - 1)  f(n)     ]    =  [ 0   1 ]n
    [f(n)      f(n + 1) ]       [ 1   1 ] 

    Time Complexity - O(logn), Space Complexity - O(1)  -  留给下次解。

    http://www.geeksforgeeks.org/program-for-nth-fibonacci-number/ 

    Reference:

    https://leetcode.com/discuss/16866/basically-its-a-fibonacci

    https://leetcode.com/discuss/71958/using-the-fibonacci-formular-to-get-the-answer-directly

    https://leetcode.com/discuss/42044/3-4-short-lines-in-every-language

    https://www.zhihu.com/question/23995189                     - 动态规划 

    http://www.hawstein.com/posts/dp-novice-to-advanced.html

    http://kukuruku.co/hub/algorithms/the-nth-fibonacci-number-in-olog-n

  • 相关阅读:
    分布式进程
    T1008 选数 codevs
    P1364 医院设置 洛谷
    T1046 旅行家的预算 codevs
    T1164 统计数字 codevs
    codevs——T1860 最大数||洛谷——P1107 最大整数
    手动脱Mole Box V2.6.5壳实战
    手动脱FSG壳实战
    手动脱NsPacK壳实战
    手动脱UPX 壳实战
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4436441.html
Copyright © 2011-2022 走看看