斐波那契数列
斐波那契数列的迭代思想与改进
- 斐波拉契数列(Fibonacci sequence):
- 又称:黄金分割数列、兔子数列
- 数学家:列昂纳多·斐波那契
- 简单的理解:从第三个数字起,每个数字都等于前两个数字之和;
- 指的是这样的一个数列:
-
0,1,1,2,3,5,8,13,21,34,……
- 在数学上被以递归数列的方法定义:
-
F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2) (n>=2)
递归代码片
// 计算 递归的
// 循环往复的调用该函数
public static long computeRecursively(int n) {
if (n > 1) {
return computeRecursively(n - 1)
+ computeRecursively(n - 2);
}
}
return n;
}
减少递归次数代码片
// 第一步 优化
// 思路: 消除方法的调用但是最终还是递归,仅仅只是减少了调用的次数
public static long computeRecursivelyUp01(int n) {
if(n>1) {
long result=1;
do {
result += computeRecursivelyUp01(n-2);
n--;
}while(n>1);
return result;
}
return n;
}
- 但是还是远远达不到代码的优化需求
第二次优化
//第二步 优化
// 思想: 迭代思想 相互作用
public static long computeInteratively(int n) {
if(n>1) {
long a=0;
long b=1;
do {
long tmp=b;
b+=a;
a=tmp;
}while(--n>1);
return b;
}
return n;
}
迭代思想图解
迭代思想的进一步优化
//位运算 判断n是不是奇数
//用 n的二进制数最右边一位与1 相比较 相同为true(1) 不同为flase(0)
//相当于if(n%2==1)
//相同时为奇数 不同时为偶数
public static long computeIterative(int n) {
if (n > 1) {
long a;
long b = 1;
n--;
a = n & 1;
n /= 2;
while (n-->0) {
a += b;
b += a;
}
return b;
}
return n;
}
-
F(0)=0,1,1,2,3,5,8,13,21,34
- a+=b第一个数+第二个数生成第三个数,b+=a第三个数+第二个数生成第四个数。
- 在进行一边,a+=b,第三个数+第四个数生成四五个数,b+=a第五个数+第四个数生成第六个数。
- 以此类推。
- 所以,当n为奇数时,b输出的为偶数位上的数字。当n为偶数时,b输出的为奇数位上的数字。(故循环变量需折半n/2)
- 又因数列的前三位数字的特殊性(0,1,1),所以可以选择由0或1做数组的第一位数字来进行计算。(即可联想到 二进制、真假值。)
- a=n&1;用 n的二进制数最右边一位与1 相比较 相同为true(1) 不同为flase(0)。
- 当n为偶数时返回true(1),当n为奇数时返回false(0)。
- 当n为偶数时(a=1),b输出的为奇数位的值,而我们需要其输出偶数位上的值,即需要(a=0)做第一位运算。
- 故(n - -)/2
迭代思想代码跑得快
递归思想能不用就不用,因位跑的特别慢