第一题,常规斐波那契数列,学到了很多东西,书上的递归其实是一种效率很低的做法,因为他重复计算了很多子问题,所以用自顶向下的备忘录法或者自底向上的动态规划法效果更好。
#include<iostream>
#include<vector>
using namespace std;
class Solution {
//传统递归,耗时大
public:
int fib(int n) {
if (n == 0)return 0;
else if (n == 1)return 1;
else return fib(n - 1) + fib(n - 2);
}
};
class Solution1 {
//备忘录法
public:
int fib(int n) {
if (n < 1)return 0;
vector<int>memo(n + 1, 0);
return helper(memo, n);
}
int helper(vector<int>&memo, int n) {
//这个&没写导致了bug
if (n == 1 || n == 2)return 1;
if (memo[n] != 0)return memo[n];
memo[n] = helper(memo, n - 1) + helper(memo, n - 2);
return memo[n];
}
};
class Solution2 {
//动态规划法
public:
int fib(int n) {
if (n == 0)return 0;
if (n == 1 || n == 2)return 1;
vector<int>dp(n + 1, 0);
dp[1] = dp[2] = 1;
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
};
int main() {
Solution2 test;
cout << test.fib(4);
}
第二题,三个数累加的斐波那契,思路类似。
#include<iostream>
#include<vector>
using namespace std;
class Solution {
//常规递归
public:
int tribonacci(int n) {
if (n == 0)return 0;
else if (n == 1 || n == 2)return 1;
else return tribonacci(n - 1) + tribonacci(n - 2) + tribonacci(n - 3);
}
};
class Solution1{
//备忘录法
public:
int tribonacci(int n) {
vector<int>memo(n + 1, 0);
return helper(memo, n);
}
int helper(vector<int>&memo, int n) {
if (n == 0)return 0;
else if (n == 1 || n == 2)return 1;
memo[1] = memo[2] = 1;
if (memo[n] != 0)return memo[n];
memo[n] = helper(memo, n - 1) + helper(memo, n - 2) + helper(memo, n - 3);
return memo[n];
}
};
class Solution2 {
//动态规划法
public:
int tribonacci(int n) {
if (n == 0)return 0;
else if (n == 1 || n == 2)return 1;
vector<int>dp(n + 1, 0);
dp[1] = dp[2] = 1;
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
}
return dp[n];
}
};
int main() {
Solution1 test;
cout << test.tribonacci(4);
}