70. Climbing Stairs

来源:互联网 发布:欧洲卡车模拟2mac联机 编辑:程序博客网 时间:2024/06/06 02:00
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?
Note: Given n will be a positive integer.

Example 1:
Input:2
Output:  2
Explanation:  There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps

Example 2:
Input:3
Output:  3
Explanation:  There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step

一道很经典的题目 爬楼梯 一次可以上一级台阶 也可以上两级 问上n级台阶有多少种方式
设用T(i)表示上i级台阶 有两种方式 
1.先上前i-1级 然后上最后一级
2.线上前i-2级 然后上最后两级
所以 T(i) = T(i-1) + T(i-2)

很容易想到递归做法
public class Solution {    public int climbStairs(int n) {        climb_Stairs(0, n);    }    public int climb_Stairs(int i, int n) {        if (i > n) {            return 0;        }        if (i == n) {            return 1;        }        return climb_Stairs(i + 1, n) + climb_Stairs(i + 2, n);    }}

时间复杂度O(n^2) 会发现这里面有重复计算
我们以T(n)表示爬n层台阶的方式 
T(4)=T(3)+T(2) 
T(3)=T(2)+T(1)
T(2)会被计算两次 随着台阶数的增多 重复计算会越来越多

所以采取dynamic programming 存储计算结果 避免重复计算
public class Solution {    public int climbStairs(int n) {        if (n == 1) {            return 1;        }        int[] dp = new int[n + 1];        dp[1] = 1;        dp[2] = 2;        for (int i = 3; i <= n; i++) {            dp[i] = dp[i - 1] + dp[i - 2];        }        return dp[n];    }}


没想到dp的基础上还可以优化空间
从表达式T(n) = T(n-1) + T(n-2) 发现和Fibonacci Number的表达式相同 所以可以采取相同办法求解
public class Solution {    public int climbStairs(int n) {        if (n == 1) {            return 1;        }        int first = 1;        int second = 2;        for (int i = 3; i <= n; i++) {            int third = first + second;            first = second;            second = third;        }        return second;    }}


可以这样想 每次计算都只需要前两次的计算结果 并不需要存储所有计算结果
时间复杂度O(n) 空间复杂度O(1)
原创粉丝点击