1.暴力递归
int fib(int n) {
if (n == 0) {
return 0;
}
if (n == 1 || n == 2) {
return 1;
}
return fib(n - 1) + fib(n - 2);
}
由于暴力递归斐波那契数列问题,时间复杂度为O(2^n),并且有很多重复计算。所以有针对重复子问题进行简化。简化的方法有两种,备忘录法和DPTable法。
2.备忘录法
自定向下计算的方法。
int fib(int N) {
if (N = 0) {
return 0
}
int arr[] = new int[N+1];
return helper(arr, N);
}
int helper(int[] arr, int n) {
if (n == 1 || n == 2) {
return 1;
}
//已经计算过,防止重复计算。
if (arr[n] != 0) {
return arr[n];
}
helper(arr, n-1) + helper(arr, n-2);
return arr[n];
}
3.dp数组迭代解法
int fib(int N) {
if (N == 0) {
return 0;
}
if (N == 1 || N == 2) {
return 1;
}
int dp[] = new int[N + 1];
//基本case
dp[1] = dp[2] = 1;
for (int i = 3; i <= N;i++;) {
dp[i] = dp[i-1] + dp[i+1];
}
return dp[N];
}
4. 由于斐波那契问题只需要保存当前的前两个数字的状态,所以不需要用数组把所有数字保存起来。所以最优解如下:
int fib(int N) {
if (N == 0) {
return 0;
}
if (N == 1 || N == 2) {
return 1;
}
int cur = 1;
int prev = 1;
for (int i = 3; i <= N; i++) {
int sum = cur + prev;
prev = cur;
cur = sum;
}
return cur;
}