一、斐波那契数列
题目:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。n<=39
思路:
1、用递归,系统会让一个超大的n来让Stack Overflow,所以递归就不考虑了。使用迭代。
2、考虑负数,极限,算法的时间空间复杂度
斐波那契数,注意:本题目n从1开始,f(0)=0;
f(n)= 1 n=1;
1 n=2;
f(n-1)+f(n-2) n>2;
public class Solution7 {
public int Fibonacci(int n) {
if(n<=0) return 0;
if(n==1||n==2) return 1;
else{
return Fibonacci(n-1)+Fibonacci(n-2);
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Solution7 sol = new Solution7();
System.out.println("输入n:");
while(scanner.hasNext()){
int n = scanner.nextInt();
System.out.println("第"+n+"项为"+sol.Fibonacci(n));
}
}
}
二、跳台阶
题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
思路:
a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1);
b.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2)
c.由a\b假设可以得出总跳法为: f(n) = f(n-1) + f(n-2)
d.然后通过实际的情况可以得出:只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2
e.可以发现最终得出的是斐波那契数列的另一种形式;
f. 当前台阶的跳法总数=当前台阶后退一阶的台阶的跳法总数+当前台阶后退二阶的台阶的跳法总数
注意:本题目f(1)=1,f(2)=2;
f(n)= 1 n=1;
2 n=2;
f(n-1)+f(n-2) n>2;
public class Solution {
public int JumpFloor(int target) {
if(target<=0){return -1;}
if(target==1){return 1;}
if(target==2){return 2;}
//第一阶和第二阶考虑过了,初始当前台阶为第三阶,向后迭代
int s1 =1;
int s2 =2;
int s =0;
for(int i=2;i<target;i++){
s = s1 + s2;
s1 = s2;
s2 = s;
}
return s;
}
public static void main(String[] args) {
Solution s = new Solution();
System.out.println(s.JumpFloor(4));
}
}
或
public class Solution6 {
public int JumpFloor(int target) {
if (target <=0 )
return -1;
else if (target == 1)
return 1;
else if (target == 2)
return 2;
else {
//第一阶和第二阶考虑过了,初始当前台阶为第三阶,向后迭代
return JumpFloor(target - 1) + JumpFloor(target - 2);
}
}
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
System.out.println("请输入台阶数");
while (scanner.hasNext()) {
int target = scanner.nextInt();
Solution6 s = new Solution6();
System.out.println(s.JumpFloor(target));
}
}
}
三、变态跳台阶
题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
思路:
关于本题,前提是n个台阶会有一次n阶的跳法。分析如下:
f(1) = 1
f(2) = f(2-1) + f(2-2) //f(2-2) 表示2阶一次跳2阶的次数。
f(3) = f(3-1) + f(3-2) + f(3-3)
…
f(n) = f(n-1) + f(n-2) + f(n-3) + … + f(n-(n-1)) + f(n-n)
说明:
1)这里的f(n) 代表的是n个台阶有一次1,2,…n阶的 跳法数。
2)n = 1时,只有1种跳法,f(1) = 1
3) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2)
4) n = 3时,会有三种跳得方式,1阶、2阶、3阶,
那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3)
因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)
5) n = n时,会有n中跳的方式,1阶、2阶…n阶,得出结论:
f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + ... + f(n-1)
6) 由以上已经是一种结论,但是为了简单,我们可以继续简化:
f(n-1) = f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)
f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) = f(n-1) + f(n-1)
可以得出:
f(n) = 2*f(n-1)
7) 得出最终结论,在n阶台阶,一次有1、2、…n阶的跳的方式时,总得跳法为:
f(n)= 1 n=0;
1 n=1;
2*f(n-1) n>2;
注意:本题目f(1)=1,f(2)=2。f(0)=1需要单独提出,相当于f(n-n)表明可以一次可以跳到顶点。
import java.util.Scanner;
public class Solution {
public int JumpFloorII(int target) {
if(target<=0) return 0;
else if(target==1) return 1;
else{
return 2 * JumpFloorII(target - 1);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Solution sol = new Solution();
System.out.println("输入target:");
while(scanner.hasNext()){
int n = scanner.nextInt();
System.out.println(sol.JumpFloorII(n));
}
}
}
或者
public int JumpFloorII(int target) {
//计算2的次方可以通过移位代替
return 1<<(target-1);
}