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个台阶,问有多少种不同的方式可以到达楼梯的顶端。
note:给定的n是一个正整数。
思路1:开始想的直接用排列组合的方法解决。考虑有多少种1和2的个数组合,然后用排列组合的方法计算。
但台阶数到达38后,就存在内存溢出的问题
public int climbStairs(int n) { if(n == 0) return 0; int count2 = n / 2; int count = 1, count1 = 0, sum = 0; for(int i = 1; i <= count2; i++){ count1 = n - i * 2; if(count1 == 0) count++; else{ sum = count1 + i; count += CFun(count1, sum); } } return count; } public int CFun(int count1, int sum){ int c = 0; c = JieCheng(sum) / (JieCheng(count1) * JieCheng(sum - count1)); return c; } public int JieCheng(int num){ int product = 1; for(int i = 2; i <= num; i++){ product *= i;//存在溢出问题 } return product; }
思路2:看了LeetCode提供的答案,才知道要使用动态规划的思想
当n为1时,f(n) = 1;即台阶数为1时,有一种方法;
当n为2时,f(n) = 2;即台阶数为2时,有两种方法;
····
思考:
当我们要走上n级台阶,必然是从n - 1级台阶迈一步,或者是从n - 2级台阶迈两步,
所以到达n级台阶的方法数必然是到达n - 1级台阶的方法数 加上 到达n - 2级台阶的方法数之和。
即f(n) = f(n - 1) + f(n - 2).
我们用dp[n]表示动态规划表,dp[i](1<= i <= n)表示到达第i级台阶的方法数。
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]; }
思路3:跟思路2本质一样,但去掉了数组,只用两个整型变量和来存储过程值。
public int climbStairs(int n){ if(n == 1) return 1; int first = 1, second = 2, third = 0; for(int i = 3; i <= n; i++){ third = first + second; first = second; second = third; } return second; }
参考:http://blog.csdn.net/uestclr/article/details/50760563