05 用两个栈实现队列

题目描述

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

思路:

栈先进后出,队列先进先出

push操作时用stack1存放,pop操作时,若stack2为空则把stack1的值依次弹出放入stack2中,直到stack1为空,此时最早进来的元素到了stack2的栈顶,弹出即可,若stack2不为空则直接弹出栈顶元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution
{
public:
void push(int node) {
stack1.push(node);
}

int pop() {
int a;
if(stack2.empty()){
while(!stack1.empty()){
a=stack1.top();
stack1.pop();
stack2.push(a);
}
stack2.pop();
}
else {
a=stack2.top();
stack2.pop();
}
return a;
}

private:
stack<int> stack1;
stack<int> stack2;
};

06 旋转数组的最小数字

题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

思路:

此题为二分查找的变形,根据题意,旋转数组将数组分为前后两段非递减数列
若mid<right则最小数在mid左边,可能就是mid,right=mid
若mid>=right则最小数在mid右边,l=mid+1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if(rotateArray.size()==0)return 0;
int l=0,r=rotateArray.size()-1;
while(l<r){
int mid=l+(r-l)/2;
if(rotateArray[mid]>=rotateArray[r]){
l=mid+1;
}
else{
r=mid;
}
}
return rotateArray[r];
}
};

ps:在牛客网提交代码时添加以下代码会提高运行时间,主要因为C++中的std :: cin和std :: cout为了兼容C,保证在代码中同时出现std :: cin和scanf或std :: cout和printf时输出不发生混乱,所以C++用一个流缓冲区来同步C的标准流。通过ios::sync_with_stdio函数可以解除这种同步,让std :: cin和std :: cout不再经过缓冲区,自然就节省了许多时间。cin.tie(nullptr)则是解除std :: cin和std :: cout之间的绑定,降低IO负担使效率提升。

1
2
3
4
5
static int x=[]{
std::ios::sync_with_stdio(false);
cin.tie(NULL);
return 0;
}();

07 斐波那契数列

题目描述

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。

n<=39

思路:

斐波那契数列问题是典型的动态规划问题,状态转移方程为a[n]=a[n-1]+a[n-1]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
int Fibonacci(int n) {
if(n==0)return 0;
if(n==1)return 1;
int first=0,second=1,current;
for(int i=2;i<=n;i++){
current=first+second;
first=second;
second=current;
}
return current;
}
};