用两个栈实现队列
题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
思路:
1、当插入时,直接插入 stack1
2、当弹出时,当 stack2 不为空,弹出 stack2 栈顶元素,如果 stack2 为空,将 stack1 中的全部数逐个出栈入栈 stack2,再弹出 stack2 栈顶元素
class Solution
{
public:
void push(int node) {
stack1.push(node);
}
int pop() {
//当弹出时,当 stack2 不为空,弹出 stack2 栈顶元素,
//如果 stack2 为空,将 stack1 中的全部数逐个出栈入栈 stack2,
//再弹出 stack2 栈顶元素
if(stack2.empty())
{
while(!stack1.empty())
{
stack2.push(stack1.top());
stack1.pop();
}
}
int ret = stack2.top();
stack2.pop();
return ret;
}
private:
stack<int> stack1;
stack<int> stack2;
};
注意:这里实际上我自己忘了C++ stack/vector/deque的一些操作,所以这里在记录一下巩固一下。
栈(stack)
//头文件
#include<stack>
//常用方法
empty() //堆栈为空则返回真
pop() //移除栈顶元素
push() //在栈顶增加元素
size() //返回栈中元素数目
top() //返回栈顶元素
队列(queue)
//头文件
#include<queue>
//常用方法
empty() 判断队列是否为空,返回类型为bool
size() 返回队列中元素的个数
front() 返回队列队首元素
back() 返回队列队尾元素
push(ele) 将元素ele插入到队尾
pop 队首元素出队
向量(vector)
#include<vector>//头文件
//常用方法
c.clear() 移除容器中所有数据。
c.empty() 判断容器是否为空。
c.erase(pos) 删除pos位置的数据
c.erase(beg,end) 删除[beg,end)区间的数据
c.front() 传回第一个数据。
c.insert(pos,elem) 在pos位置插入一个elem拷贝
c.pop_back() 删除最后一个数据。
c.push_back(elem) 在尾部加入一个数据。
c.resize(num) 重新设置该容器的大小
c.size() 回容器中实际数据的个数。
c.begin() 返回指向容器第一个元素的迭代器
c.end() 返回指向容器最后一个元素的迭代器
旋转数组最小数字
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路(二分查找思想):
参考:https://www.nowcoder.com/questionTerminal/9f3231a991af4f55b95579b44b7a01ba?answerType=1&f=discussion
二分查找的 mid
如果落在左半边,那么就 lo=mid+1
,如果落在右半边,就减小 hi=mid
。不断缩小范围,最终,lo
一定会掉到最低点。但是要如何判断 mid
落在那一边呢。因为左半边 >= 右半边,如果原数组是严格递增的,你可以说,当 a[mid] > a[0]
那就是左半边。但是考虑下面这幅图:
如果原数组只有开始部分递增,之后很长一段都是平坦的,那么旋转后可能是上图的样子。a[mid] == a[lo] == a[hi]
,根本没法判断 mid 在那边。解决的方法很简单:
while(a[lo] == a[hi]){ ++lo; --hi; }
这样操作以后,一定有 a[lo] > a[hi]
,一旦 lo
掉到了最低点,这个条件就不成立了。判断 mid 在左在右也很简单了,如果 a[mid] >= a[lo]
那就是左边。如果 a[mid] <= a[hi]
那就是右边。
如果在左边,那就 lo=mid+1
,这样把 lo 向右边推进。如果在右边,为了避免 hi
爬到了左边去 hi=mid
即可。最终终止条件,就是 lo
落到了最低点。
class Solution {
public:
int minNumberInRotateArray(vector<int> a) {
if(a.size() == 0) return 0;
int lo = 0, hi = a.size() - 1;
//防止原数组只有开始部分递增,之后很长一段都是平坦的
while(a[lo] == a[hi])
{
++ lo;
-- hi;
}
/*
if (a.size() == 0) return 0;
int lo = 0, hi = a.size()-1;
while(a[lo] == a[hi]){
++lo;
--hi;
}*/
while(a[lo] > a[hi]){
int mid = lo + (hi-lo) / 2;
if(a[mid] >= a[lo]){
lo = mid + 1;
}else if(a[mid] <= a[hi]){
hi = mid;
}
}
return a[lo];
}
};