The Fibonacci numbers, commonly denoted F(n) form a sequence, called the Fibonacci sequence, such that each number is the sum of the two preceding ones, starting from 0 and 1. That is,
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), for N > 1.
Given N, calculate F(N).
Example 1:
Input: 2
Output: 1
Explanation: F(2) = F(1) + F(0) = 1 + 0 = 1.
Example 2:
Input: 3
Output: 2
Explanation: F(3) = F(2) + F(1) = 1 + 1 = 2.
Example 3:
Input: 4
Output: 3
Explanation: F(4) = F(3) + F(2) = 2 + 1 = 3.
Note:
0 ≤ N ≤ 30.
方法一:递归调用
/**
* @param {number} N
* @return {number}
*/
// 方法一:
var fib = function(N) {
if(N == 0) return 0;
if(N == 1) return 1;
if(N > 1) return fib(N-1) + fib(N-2);
};
Time complexity : O(2^N). Space complexity : O(N).
方法二:公式计算(未实现) 其实我感觉斐波那契序列可以通过杨辉三角推导出结论,但是以我有限的智商暂时没办法的总结出规律。(简直就是博客LeetCode_09的再现)
方法二:自底向上,循环计算
/**
* @param {number} N
* @return {number}
*/
// 方法二:
var fib = function(N) {
if(N <= 1) return N;
let tempArr = [0, 1];
for(let i = 2; i <= N; i++) {
tempArr[i] = tempArr[i-1] + tempArr[i-2];
}
return tempArr[N];
};
效率比方法一优秀很多:
方法三:Top-Down Approach using Memoization(没看懂,跟递归的差异性在哪里?)
/**
* @param {number} N
* @return {number}
*/
// 方法三:
let cache = [];
var fib = function(N) {
if(N <= 1) return N;
cache[0] = 0;
cache[1] = 1;
return memoize(N);
};
function memoize(N) {
if(cache[N] != null) {
return cache[N];
}
cache[N] = memoize(N-1) + memoize(N-2);
return memoize(N);
}
有点不太明白,同样是用了递归,这个解法只是将公式保存了一下,为什么时间复杂度就从O(2^N)变成了O(N)??
方法四:Iterative Top-Down Approach 这个其实就是方法二,只是不用数组存储计算的结果,只用三个变量做桥接;
/**
* @param {number} N
* @return {number}
*/
// 方法四:
var fib = function(N) {
if(N <= 1) return N;
if(N == 2) return 1;
let current = 0;
let pre1 = 1;
let pre2 = 1;
for(let i = 3; i <= N; i++) {
current = pre1 + pre2;
pre2 = pre1;
pre1 = current;
}
return current;
}
方法五:Matrix Exponentiation 矩阵指数(我又没看懂,所以就不用JavaScript复现了)
方法六:数学运算:斐波那契数列和黄金分割比的关系
/**
* @param {number} N
* @return {number}
*/
// 方法六:
var fib = function(N) {
let goldenRatio = (1 + Math.sqrt(5)) / 2;
return parseInt( Math.round(Math.pow(goldenRatio, N)/ Math.sqrt(5)) );
}