Climbing Stairs

爬楼梯问题,每次可以选择爬一阶或者两阶,问总共有多少种方法?

1、一眼望去,直接暴力递归(果然Time Limit Exceeded)

	static int cout=0;
	public int climbStairs(int n) {
		cout=0;
		if(n==0)
			return 0;
		DFS(n, 0);
		return cout;
	}
	public void DFS(int n,int st)
	{
		if(st>=n)
		{
			if(st==n)
				cout++;
		}
		if(st+1<=n){
			DFS(n,st+1);
		}
		if(st+2<=n) {
			DFS(n,st+2);
		}
	}

2、在各路大佬的帮助下,发现这是一个Fibonacci 问题,即著名的兔子繁衍问题

最开始有1对兔子,兔子在出生后第3个月起每个月都生一对小兔子,假设兔子不存在死亡的情况,请问10个月后有多少对兔子?

第一个月:1对兔子

第二个月:1对兔子

第三个月:2对兔子(一对老兔子生一对小兔子)

第四个月:3对兔子(一对老兔子又生了一对小兔子)

第五个月:5对兔子(一对老兔子第二次生了一对小兔子,第一次生的一对小兔子也生了一对新兔子)

...

这和爬楼梯问题是十分相似的,直接用递归的方式之所以超时,是因为爬第n阶楼梯的方法数是可以由第n-1阶和第n-2阶推导出来的,所以导致递归很多计算都是重复的

n=1,1

n=2,11,2

n=3,111,21,12

n=4,1111,211,121,112,22

n=5,11111,2111,1211,1121,221,1112,212,122

...

细心的朋友会发现,f(n)=f(n-1)+f(n-2)

如n=4,爬4阶楼梯的情况可以划分为以下两种:

1、爬到3阶楼梯,然后再一口气爬1阶

2、爬到2阶楼梯,然后再一口气爬2阶

知道了方法,现在就是如何求Fibonacci的问题了?

递归大法好,虽然简单,但是还是超时了

	public int climbStairs(int n) {
		if(n==1)
			return 1;
		if(n==2)
			return 2;
		return climbStairs(n-1)+climbStairs(n-2);
	}

还是老老实实用循环靠谱,果然0ms,不负众望

	public int climbStairs(int n) {
		if(n==1)
			return 1;
		Vector<Integer> st=new Vector<Integer>();
		st.add(1);
		st.add(1);
		for(int i=2;i<=n;i++)
		{
			st.add(i, st.get(i-1)+st.get(i-2));
		}
		return st.get(n);
	}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值