代码展示:
package com.jiang;
public class Code01_Fibonacci {
public static int getFibonacci(int n) {
//如果n<=1 其实都是返回的本身的值
if(n <= 1) {
return n;
}
//例如 传入n=3 求第1+第二位的值
return getFibonacci(n - 1) + getFibonacci(n - 2);
}
public static void main(String[] args) {
System.out.println(getFibonacci(7));
}
}
// getFibonacci(7) = 13
分析问题:
如果getFibonacci()参数传入的是177,那么你会发现他会进入很漫长的计算时间,迟迟得不到结果。
当然,最终问题是因为递归导致栈空间不够用,从而栈溢出,这将在后面详细讲解,目前有一定概念即可。
代码展示:
public static int getFibonacci2(int n) {
//如果n<=1 其实都是返回的本身的值
if(n <= 1) {
return n;
}
//定义第一个和第二个的值
int first = 0;
int second = 1;
//以 get(3)为例
//i需要循环3-1 = 2次
for(int i = 0; i<n-1;i++) {
//第一次循环 sum初始是1
//第二次循环 sum = 1+1 = 2
int sum = first + second;
//第一次循环 first = 1;
//第二次循环 first = 1;
first = second;
//第一次循环 second = 1;
//第二次循环 second = 2;
second = sum;
}
return second;
}
此时我们输入177也可以快速的进行反应,这就有一个新的概念,复杂度
public static int getFibonacciByTezheng(int n) {
double c = Math.sqrt(5);
return (int)((Math.pow((1+c)/2, n) - Math.pow((1 - c) / 2, n)) /c);
}
时间复杂度:视为 O(1),不进行过多赘述,涉及到线性代数特征方程的知识点
执行次数 | 复杂度 | 非正式术语 |
---|---|---|
12 | O(1) | 常数阶 |
2n + 3 | O(n) | 线性阶 |
4n^2 + 2n + 6 | O(n^2) | 平方阶 |
4log2n + 25 | O(logn) | 对数阶 |
3n + 2nlog3n + 15 | O(nlogn) | nlogn阶 |
4n^3 + 3n^2 + 22n + 100 | O(n^3) | 立方阶 |
2^n | O(2^n) | 指数阶 |
数据规模较小时
数据规模较大时
getFibonacciByFor循环
public static int getFibonacciByFor(int n) {
if(n <= 1) {
return n;
}
int first = 0;
int second = 1;
for(int i = 0; i<n-1;i++) {
int sum = first + second;
first = second;
second = sum;
}
return second;
}
该复杂度可以分析出来 是由n控制的 是O(n)复杂度
getFibonacciBy递归
public static int getFibonacciByDigui(int n) {
if(n <= 1) {
return n;
}
return getFibonacci(n - 1) + getFibonacci(n - 2);
}
该方法中 最重要的是 最终return后的+的操作
即复杂度是O(2^n),它的运行速度要大于O(n)
原文:https://www.cnblogs.com/pengcode/p/14839299.html