最近高考,刚好无意间看到“程序员高考题”,所以随便找了一题做了做。
1、题目
程序员小李的女朋友不仅颜值高、大长腿、还爱运动,她在爬楼梯的时候喜欢跨一个台阶、也喜欢跨两个或者三个台阶,假如一个楼梯有N个台阶,请问她有多少种爬法?请写出程序,语言不限!
2、解
打印每步信息版本
public class NewTest {
private static int num = 0;
public static void main(String[] args) {
int n = 10; //台阶数
List<Integer> list = new LinkedList<>(); //保存步数信息
doSomething(n - 1, list, 1, 0);
doSomething(n - 2, list, 2, 0);
doSomething(n - 3, list, 3, 0);
System.out.println("num=" + num); //方案总数量
}
/**
* 走台阶
* @param n 剩余台阶数
* @param list 走的步数
* @param m 当前走的步数
* @param w 当前走的第几步,从0开始
*/
private static void doSomething(int n, List<Integer> list, int m, int w) {
if (n < 0) {
//最后一步步子迈大了,台阶阶数不够
return;
}
list.add(m); // 没有结束,记录下当前迈的步数
if (n == 0) {
//正确走完台阶
num++;
System.out.println(list); //输出结果
list.remove(w); //删除当前步数,试其他结果
return;
}
//分别使用三种步数
doSomething(n - 1, list, 1, w + 1);
doSomething(n - 2, list, 2, w + 1);
doSomething(n - 3, list, 3, w + 1);
//调用完 删除当前步(说明当前情况已经走完了,回退步数)
list.remove(w);
}
}
简洁版本
public class NewTest {
private static int num = 0;
public static void main(String[] args) {
long time = System.currentTimeMillis();
int n = 10;
doSomething(n);
System.out.println("num=" + num);
long endTime = System.currentTimeMillis();
System.out.println("花费时间:" + (endTime - time) + "ms");
}
/**
* 走台阶
* @param n 剩余台阶数
*/
private static void doSomething(int n) {
if (n < 0) {
return;
}
if (n == 0) {
num++;
return;
}
doSomething(n - 1);
doSomething(n - 2);
doSomething(n - 3);
}
}
3、逻辑
假设第一步走1、2、3步,总步数减少1、2、3.也就是n-1,n-2,n-3,接下来的步数同理,递归调用.当n刚刚等于0时,说明改方案步数正好走完楼梯。打印正确方案,计数加一。如果n小于0,说明最后一步走多了,不计在方案中。每当一个递归方法体走完,删除对应位置的数据,保证数据的不会重复记录。
该写法没有精心打磨,有意见或者问题,请在评论中指出以便作者改正,谢谢。