有n步台阶,一次只能上1步或2步,共有多少种走法?
方法1 递归
package com.yzx.test01;
/**
* 编程题:
* 有n步台阶,一次只能上1步或2步,共有多少种走法?
* 思路: 递归
* n=1 ——> 一步 ——> f(1)=1
* n=2 ——> (1)一步一步 (2)直接两步 ——> f(2) =2
* n=3 ——> (1)先到达第f(1),然后直接从f(1)直接跨2步
* (2)先到达f(2),然后直接从f(2)跨1步 f(3)=f(1)+f(2)
*
*
* n=x ——>(1) 先到达f(x-2),然后从f(x-2)直接垮2步
* (2) 先到达f(x-1),然后从f(x-1)跨1步 f(x) =f(x-2)+f(x-1)
*
*
*/
public class TestStep2 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
TestStep2 step = new TestStep2();
System.out.println(step.f(40));
long end = System.currentTimeMillis();
System.out.println(end-start); //565ms
}
public int f(int n){
if (n<1){
throw new IllegalArgumentException(n+"n不能小于1");
}
if (n== 1 || n ==2){
return n;
}else {
return f(n-2) + f(n-1);
}
}
}
优点:代码精简 易懂,容易编写。
缺点:开销较大,容易造成内存溢出。
方法2 迭代(使用 两个变量分别存上次的 相加的步数)
package com.yzx.test01;
/**
* 编程题:
* 有n步台阶,一次只能上1步或2步,共有多少种走法?
* 思路: 迭代循环
* n=1 ——> 一步 ——> f(1)=1
* n=2 ——> (1)一步一步 (2)直接两步 ——> f(2) =2
* n=3 ——> (1)先到达第f(1),然后直接从f(1)直接跨2步
* (2)先到达f(2),然后直接从f(2)跨1步 f(3)=f(1)+f(2)
*
*
* n=x ——>(1) 先到达f(x-2),然后从f(x-2)直接垮2步
* (2) 先到达f(x-1),然后从f(x-1)跨1步 f(x) =f(x-2)+f(x-1)
*
*
*/
public class TestStep {
public static void main(String[] args) {
long start = System.currentTimeMillis();
TestStep step = new TestStep();
System.out.println(step.f(40));
long end = System.currentTimeMillis();
System.out.println(end-start); //小于1ms
}
public int f(int n){
if (n<1){
throw new IllegalArgumentException(n+"n不能小于1");
}
if (n== 1 || n ==2){
return n;
}
int one = 2; //初始化走到第二级台阶的走法 f(2) = 2
int two = 1; //初始化走到第一级台阶的走法 f(1) =1
int sum = 0;
//从第三步开始算起
for(int i = 3 ;i <=n ;i++){
sum = one + two;
//重新为one two 赋值
two = one;
one = sum;
}
return sum;
}
}
优点:速率快。
缺点:代码不易懂。