刷题计划(第1天)
时间:2022.4.16
题数:2
题目类型:栈&动态规划&线性代数
1.斐波那契数列
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
第一次尝试了最简单的递归:
class Solution {
public:
int fib(int n) {
if(n==0||n==1) return n;
return fib(n-1)+fib(n-2);
}
};
第二次使用循环,避免递归造成的过多浪费(官方解法类似)
class Solution {
public:
int fib(int n) {
if(n==0||n==1) return n;
int a=1,b=0; //用a和b来模拟0和1
for(int i=1;i<n;i++){ //注意循环边界条件
a=a+b;
b=a-b;
a%=1000000007;
}
return a;
}
};
补一个官方解法(1):
class Solution {
public:
int fib(int n) {
int MOD = 1000000007;
if (n < 2) {
return n;
}
int p = 0, q = 0, r = 1;
for (int i = 2; i <= n; ++i) {
p = q;
q = r;
r = (p + q)%MOD;
}
return r;
}
};
第3次用了官方的第二个解法:矩阵快速幂(很难想到)
class Solution {
public:
int fib(int n) {
if(n==0||n==1) return n;
vector<vector<long>> q{{1,1},{1,0}};
vector<vector<long>> res=pow(q,n-1);
return res[0][0];
}
vector<vector<long>> pow(vector<vector<long>>& a,int n){
vector<vector<long>> ret{{1,0},{0,1}};
while(n>0){
if(n&1){
ret=multiply(ret,a);
}
n>>=1;
a = multiply(a, a);
}
return ret;
}
vector<vector<long>> multiply(vector<vector<long>>& a, vector<vector<long>>& b) {
vector<vector<long>> c{{0, 0}, {0, 0}};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
c[i][j] = (a[i][0] * b[0][j] + a[i][1] * b[1][j]) %1000000007;
}
}
return c;
}
};
2.利用两个栈实现队列
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
输入与输出示范:(ps.官方的输入输出有点难懂,可以去这道题的评论区的老哥详解)
这里运用了栈的设计,实现了队列,具体是一个作为进栈,另外一个作为出栈,在两次先进后出后变成了先进先出。
private:
stack<int> inStack,outStack;
void ininout(){ //如果在in里面还有元素,则输入进out里面
while(!inStack.empty()){
outStack.push(inStack.top());
inStack.pop();
}
}
public:
CQueue() {
}
void appendTail(int value) {
inStack.push(value);
}
int deleteHead() {
if(outStack.empty()){
if(inStack.empty()){
return -1;
}
ininout();
}
int value=outStack.top();
outStack.pop();
return value;
}
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
3.
总结
栈的设计和应用,动态规划已知状态转移方程和结合线性代数,斐波那契数列的求解(非递归)