剑指offer-青蛙跳台阶问题

本文探讨了一只青蛙跳上不同台阶的总跳法,解析了递归、记忆化递归和动态规划三种解题策略。重点介绍了动态规划的最优解法,通过斐波那契数列的性质避免了重复计算,并解释了为何在计算过程中需要对1000000007取模以防止溢出。
摘要由CSDN通过智能技术生成

(1)一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法。
(2)一只青蛙一次可以跳上1级台阶,也可以跳上2 级……它也可以跳上n 级,此时该青蛙跳上一个n级的台阶总共有多少种跳法?
分析:1)当n = 1, 只有1中跳法;当n = 2时,有两种跳法;当n = 3 时,有3种跳法;当n = 4时,有5种跳法;当n = 5时,有8种跳法;.......
规律类似于Fibonacci数列

解题思路:

思路一:递归法

把f(n)问题拆分成f(n-1)和f(n-2)子问题,缺点:大量重复计算。

 

int Fib(int n) {
	if (n<=2)
	{
		return n;
	}
	else
	{
		return Fib(n - 1) + Fib(n - 2);
	}
}

思路二:记忆化递归法

在递归法的基础上,新建一个长度为n的数组,用于存储f(0)至f(n)的数值,重复时直接在数组取用,避免了重复的递归计算,缺点:需要使用O(N)的额外空间。

思路三:动态规划算法(最佳解法)

 以斐波那契数列性质f(n + 1) = f(n) + f(n - 1)为转移方程。

int numWays(int n) {
	if (n<=1)
	{
		return 1;
	}
	int a = 1;
	int b = 1;
	int c = 0;
	for (int i = 2; i <=n; i++)
	{
		c = (a + b) % 1000000007;
		a = b;
		b = c;
	}
	return c;
}

时间复杂度:O(N)
空间复杂度 :O(1)

为什么要对1000000007取模?

因为1000000007是一个质数(素数),对质数取余能最大程度避免冲突 

int32位的最大值为2147483647,所以对于int32位来说1000000007足够大

int64位的最大值为2^63-1,对于1000000007来说它的平方不会在int64中溢出

取模前 f(43) = 701408733, f(44) = 1134903170, f(45) = 1836311903, 但是 f(46) > 2147483647结果就溢出了。
取模后 f(43) = 701408733, f(44) = 134903163 , f(45) = 836311896, f(46) = 971215059没有溢出。取模之后能够计算更多的情况,如 f(46)。这道题的测试答案与取模后的结果一致。

总而言之,模1000000007是通用做法,大数情况是为了防止溢出。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值