【LeetCode刷题】
1. 题目:155.最小栈
思路分析:
从解释那段代码调用,我们可以知道MinStack
是一个很普通的栈,就多一个函数而已。所以就可以在MinStack
的属性里加一个stack<int>
,再加一个可以时刻记录栈内最小值的容器就可以。
思路1:两个栈实现最小栈
设计两个栈,一个正常栈(s1),一个用于记录正常栈每次push或者pop后的最小值(minS)。要获得MinStack的最小值,只需要访问minS的top就可以。
代码实现:
class MinStack {
public:
MinStack() {}
void push(int val) {
s1.push(val);
if(minS.empty()||val<minS.top()) minS.push(val);
else minS.push(minS.top());
}
void pop() {
s1.pop();
minS.pop();
}
int top() {
return s1.top();
}
int getMin() {
return minS.top();
}
private:
stack<int> s1;
stack<int> minS;
};
2.题目: JZ31 栈的压入、弹出序列
思路分析:
平时我们做这样的选择题是怎么做的?自己是不是要模拟实现一下。所以这里我们也同样可以来模拟实现一下,看匹不匹配。
思路1:模拟实现
- 模拟实现,判断栈的出入顺序匹不匹配,肯定要有个栈s1。
- 再来过程,pushV把数据push到栈里,每次push后,栈顶元素与序列popV头元素(或者指针元素)对比,若相等,两个都头删(栈头删,popV指针后移),再比较,直到不相等,然后再接着pushV进栈(vector没有头删,所以用指针记录好些)。
- 结果判断:可以判断popV的指针位置,也可以判断栈s1是否已经pop完了。
代码实现:
class Solution {
public:
bool IsPopOrder(vector<int>& pushV, vector<int>& popV) {
// write code here
stack<int> s;
int j=0;
for(int i=0;i<pushV.size();i++)
{
s.push(pushV[i]);
while(!s.empty())
{
if(s.top()==popV[j])
{
s.pop();
j++;
}
else break;
}
}
return j==popV.size();
}
};
3.题目: 150.逆波兰表达式求值
思路分析:
这题的要求就是计算逆波兰表达式的值,也叫后缀表达式(运算符放到后面),计算规则很简单,主要是设计一些判断。
运算规则:符号前两个数字,通过这个运算符计算后再次存入,直到把最后一个运算符运算结束。
思路1:暴力
遍历tokens,是数字就按顺序存在容器里,遇到运算符,就取出最近插入的两个数字计算,注意前面的减后面的(减法和除法注意),然后再把计算结果返回到容器里。直到遍历完。
代码实现:
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> s;
for(int i=0;i<tokens.size();i++)
{
if(tokens[i]=="+"||tokens[i]=="-"||tokens[i]=="*"||tokens[i]=="/")
{
if(tokens[i]=="+")
{
int k=s.top();
s.pop();
k+=s.top();
s.pop();
s.push(k);
}
else if(tokens[i]=="-")
{
int k=s.top();
s.pop();
k=s.top()-k;
s.pop();
s.push(k);
}
else if(tokens[i]=="*")
{
int k=s.top();
s.pop();
k*=s.top();
s.pop();
s.push(k);
}
else if(tokens[i]=="/")
{
int k=s.top();
s.pop();
k =s.top()/k;
s.pop();
s.push(k);
}
}
else s.push(stoi(tokens[i]));
}
return s.top();
}
};
4.题目:232.用栈实现队列
思路分析:
用栈来实现队列,要从先进后出变到先进先出。
思路1:两个栈
其实只是需要一个辅助栈就可以了。正常栈push进数据,再要pop或者返回top的时候,几把数据push到辅助栈里,然后辅助栈pop、top都可以。
代码实现:
class MyQueue {
public:
void push(int x) { s1.push(x); }
int pop() {
if (s2.empty())
while (!s1.empty()) {
s2.push(s1.top());
s1.pop();
}
int k = s2.top();
s2.pop();
return k;
}
int peek() {
if (s2.empty())
while (!s1.empty()) {
s2.push(s1.top());
s1.pop();
}
return s2.top();
}
bool empty() { return s1.empty() && s2.empty(); }
stack<int> s1; //正常栈
stack<int> s2; //辅助栈
};
5.题目:225.用队列实现栈
思路分析:
这种题主要是设计,思路方面比较明确的。用队列实现栈。
思路1:一个队列实现
一个队列思路就是:一个元素进去,要保证它是在front位置,怎么保证,把前面的所有元素再一次push进队列就可以。
代码实现:
class MyStack {
public:
queue<int> q;
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
int n = q.size();
q.push(x);
for (int i = 0; i < n; i++) {
q.push(q.front());
q.pop();
}
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int r = q.front();
q.pop();
return r;
}
/** Get the top element. */
int top() {
int r = q.front();
return r;
}
/** Returns whether the stack is empty. */
bool empty() {
return q.empty();
}
};
作者:力扣官方题解
来源:力扣(LeetCode)
思路2:两个队列:入栈O(n),出栈O(1)
入栈O(n),出栈O(1): 这就说明在push时候导元素。一个栈保持空队列,每次push就往里push,再把另一个栈顺序的队列的元素全部导到这个刚push一个的元素里。然后交换两个队列,push队列依旧是空,顺序队列依旧顺序和栈要求顺序一样(pop、front就是后进的元素)
代码实现:
class MyStack {
public:
queue<int> queue1;
queue<int> queue2;
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
queue2.push(x);
while (!queue1.empty()) {
queue2.push(queue1.front());
queue1.pop();
}
swap(queue1, queue2);
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int r = queue1.front();
queue1.pop();
return r;
}
/** Get the top element. */
int top() {
int r = queue1.front();
return r;
}
/** Returns whether the stack is empty. */
bool empty() {
return queue1.empty();
}
};
作者:力扣官方题解
来源:力扣(LeetCode)
思路3:两个队列:入栈O(1),出栈O(n)
入栈O(1),出栈O(n): 这就说明pop处导元素。一个队列只是push进,不做其他处理。只有到了pop时候,就把这个队列的元素除了最后进的元素外,其他全部push到第二个队列。再次pop的话,就用第二个队列做同样的操作。top的话只需要看哪个队列不为空,返回最后一个元素就可以。
代码实现:
class MyStack {
public:
void push(int x) { q1.push(x); }
int pop() {
int k;
if (!q1.empty()) {
while (q1.size() > 1) {
q2.push(q1.front());
q1.pop();
}
k = q1.front();
q1.pop();
} else {
while (q2.size() > 1) {
q1.push(q2.front());
q2.pop();
}
k = q2.front();
q2.pop();
}
return k;
}
int top() {
if (!q1.empty())
return q1.back();
else
return q2.back();
}
bool empty() { return q1.empty() && q2.empty(); }
queue<int> q1;
queue<int> q2;
};