剑指offer10.斐波那契数列及青蛙跳台阶问题

斐波那契数列
题目描述

写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。

斐波那契数列的定义:F(0) = 0, F(1) = 1;F(N) = F(N - 1) + F(N - 2), 其中 N > 1

解析
  • 解法一:递归
    第一想法必是递归求解,代码如下,然而由代码可以看出该方法存在着大量的重复计算。当计算fib(n-1)时,会需要计算fib(n-2)和fib(n-3),而在递归完fib(n-1)后,又需要递归计算fib(n-2),而无法利用前者已计算过的值(因为并不会在内存中)。由此缺点出发,想出解法二。
public int fib(int n) {
		 if(n==0) return 0;
		 if(n==1) return 1;
		 int num = (fib(n-1)+fib(n-2))%1000000007;
		 return num;
	 }
  • 解法二:动态规划
    由于在解法一中需要重复递归计算前两个数据,因此考虑用数组保存计算得到的f(n),此时会需要消耗内存空间。动态规划的状态转移方程:F(N) = F(N - 1) + F(N - 2)。
public int fib(int n) {
		if(n==0) return 0;
		int[] array=new int[n+1];
		array[0]=0;
		array[1]=1;
		for(int i=2;i<=n;i++) {
			array[i]=(array[i-1]+array[i-2])%1000000007;
		}
		return array[n];
	}
  • 解法三:循环取余法(题解区解法)
    取余规则运算: (a + b) % p = (a % p + b % p) % p ,因此可以边运算边取模。
public int fib(int n) {
		int a=0, b=1, sum;
		for(int i=0;i<n;i++) {
			sum = (a+b)%1000000007;
			a=b;
			b=sum;
		}
		return a;
	}

青蛙跳台阶问题
题目描述

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

解析

这道题本质上是求斐波那契数列的第n项(仅仅是初始值不同)。这样理解:

  • 当n==1时,只有一种跳法,即f(1)=1,
  • 当n==2时,可以从零级台阶上直接跳两步上来,也可以从一级台阶上跳一步上来,共有2种跳法,即f(2)=2,
  • 当n==3时,可以从一级台阶上跳两步上来,也可以从二级台阶上跳一步上来,即总共有f(3)=f(2)+f(1)种跳法,
  • 同理:有n级台阶时,可以从(n-1)级台阶上跳一步上来,也可以从(n-2)级台阶上跳两步上来,总共有f(n)=f(n-1)+f(n-2)种跳法。

因此:题目可用数学化公式描述为:f(0)=1,f(1)=1,f(n)=f(n-1)+f(n-2)(当n>=2时)

 public int numWays(int n) {
		 if(n==0 || n==1) return 1;
		 int[] array = new int[n+1];
		 array[0]=1;
		 array[1]=1;
		 for(int i=2;i<=n;i++) {
			 array[i]=(array[i-1]+array[i-2])%1000000007;
		 }
		 return array[n];
	 }
public int numWays(int n) {
		 int a=1,b=1,sum;
		 if(n==0 || n==1) return a;
		 for(int i=2;i<=n;i++) {
			 sum = (a+b)%1000000007;
			 a=b;
			 b=sum;
		 }
		 return b;		
	 }	 

你可能感兴趣的:(leetcode)