509. 斐波那契数题解
题目来源:509. 斐波那契数
法一:递归方法
斐波那契数列的公式是
F
i
b
o
n
a
c
c
i
(
x
)
=
{
0
,
x = 0
1
,
x = 1
F
i
b
o
n
a
c
c
i
(
x
−
1
)
+
F
i
b
o
n
a
c
c
i
(
x
−
2
)
,
x > 1
Fibonacci(x) = \begin{cases} 0, & \text{x = 0} \\ 1, & \text{x = 1} \\ Fibonacci(x - 1) + Fibonacci(x - 2), & \text{x > 1} \end{cases}
Fibonacci(x)=⎩⎪⎨⎪⎧0,1,Fibonacci(x−1)+Fibonacci(x−2),x = 0x = 1x > 1
从规律中不难看出这是一个不断递归的过程,而退出递归的条件就是当 x 小于 2 时,因此可以使用递归进行求解
本题的数据范围是 [ 0, 30] 使用递归还可以
class Solution {
public:
int fib(int n) {
// 如果满足退出递归条件就退出
if (n == 0) return 0;
if (n == 1) return 1;
// 进行下一次的递归
return fib(n - 1) + fib(n - 2);
}
};
class Solution {
public int fib(int n) {
// 如果满足退出递归条件就退出
if (n == 0) return 0;
if (n == 1) return 1;
// 进行下一次的递归
return fib(n - 1) + fib(n - 2);
}
}
- 时间复杂度O(2n)
- 空间复杂度O(n)
动态规划
按照上面递归的思路,如上图所示,会发现,有好多结果需要反复访问,因此我们可以通过动态规划的思想来进行求解
斐波那契数列的公式是
F
i
b
o
n
a
c
c
i
(
x
)
=
{
0
,
x = 0
1
,
x = 1
F
i
b
o
n
a
c
c
i
(
x
−
1
)
+
F
i
b
o
n
a
c
c
i
(
x
−
2
)
,
x > 1
Fibonacci(x) = \begin{cases} 0, & \text{x = 0} \\ 1, & \text{x = 1} \\ Fibonacci(x - 1) + Fibonacci(x - 2), & \text{x > 1} \end{cases}
Fibonacci(x)=⎩⎪⎨⎪⎧0,1,Fibonacci(x−1)+Fibonacci(x−2),x = 0x = 1x > 1
class Solution {
public:
int fib(int n) {
// 如果为第 0 项或者第 1 项,直接返回值
if (n < 2) return n;
// 用 a 表示第 n - 1 项,b 表示第 n 项
int a = 0, b = 1;
n--;
// 循环 n - 2 次
while (n != 0) {
int temp = a + b;
a = b;
b = temp;
n--;
}
return b;
}
};
class Solution {
public int fib(int n) {
// 如果为第 0 项或者第 1 项,直接返回值
if (n < 2) return n;
// 用 a 表示第 n - 1 项,b 表示第 n 项
int a = 0, b = 1;
n--;
// 循环 n - 2 次
while (n != 0) {
int temp = a + b;
a = b;
b = temp;
n--;
}
return b;
}
}
- 时间复杂度:O(n)O(n)。
- 空间复杂度:O(1)O(1)。
法三:公式
斐波那契数列的公式是
F
i
b
o
n
a
c
c
i
(
n
)
=
1
5
∗
(
1
+
5
2
)
n
−
1
5
∗
(
1
−
5
2
)
n
Fibonacci(n)= {{1} \over {\sqrt{5}}}*({{1+\sqrt{5}} \over {2}})^n-{{1} \over {\sqrt{5}}}*({{1-\sqrt{5}} \over {2}})^n
Fibonacci(n)=51∗(21+5)n−51∗(21−5)n
class Solution {
public:
int fib(int n) {
double Sqrt = sqrt(5);
double fib = pow((1 + Sqrt) / 2, n) - pow((1 - Sqrt) / 2, n);
return (int) (fib / Sqrt);
}
};
class Solution {
public int fib(int n) {
double sqrt = Math.sqrt(5);
double fib = Math.pow((1 + sqrt) / 2, n) - Math.pow((1 - sqrt) / 2, n);
return (int) (fib / sqrt);
}
}