栈与队列
栈先入后出,队列先入先出
- stack数据结构,push()/pop()都是void返回值,找元素需要用top()
- 递归本质上就是栈实现的,调用递归会把函数、参数等压入栈中,因此递归过深就会报segment fault
232.用栈实现队列
https://leetcode.cn/problems/implement-queue-using-stacks/description/

class MyQueue {
public:
stack<int> stackIn;
stack<int> stackOut;
MyQueue() {
}
void push(int x) {
stackIn.push(x);
}
int pop() {
if(stackOut.empty()){//注意!!!!!!!
while(!stackIn.empty())
{
stackOut.push(stackIn.top());
stackIn.pop();
}
}
int cur = stackOut.top();
stackOut.pop();
return cur;
}
int peek() {
//类成员函数调用另一个成员函数用this->
int cur = this->pop();
stackOut.push(cur);
return cur;
}
bool empty() {
return stackIn.empty() && stackOut.empty();
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
225.用队列实现栈
https://leetcode.cn/problems/implement-stack-using-queues/description/

class MyStack {
public:
queue<int> q;
MyStack() {
}
void push(int x) {
q.push(x);
}
int pop() {
int size = q.size();
while(--size)
{
q.push(q.front());
q.pop();
}
int cur = q.front();
q.pop();
return cur;
}
int top() {
return q.back();
}
bool empty() {
return q.empty();
}
};
20.有效的括号
https://leetcode.cn/problems/valid-parentheses/submissions/493171286/

class Solution {
public:
bool isValid(string s) {
//先入后出,比如( ( ) ) 遇到第三个字符 先弹出第二个括号
if("" == s) return true;
if(s.size() % 2 != 0) return false;
stack<char> st;
for(int i = 0; i < s.size(); i++)
{
cout<<s[i]<<endl;
if(s[i] == '(')
st.push(')');
else if(s[i] == '[')
st.push(']');
else if(s[i] == '{')
st.push('}');
//这里是一定要用他妈的else if的 不然的话,对于() i = 0 入栈了 ) 会立即与 ( 作比较返回false!!!!!!!!!!!!!
else if(st.empty()||st.top() != s[i]) return false;
else
st.pop();
}
return st.empty();
}
};
1047.删除字符串中的所有重复项
https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/description/

//更推荐用string,因为直接有push_back和pop_back()
class Solution {
public:
string removeDuplicates(string s) {
stack<char> st;
for(int i = 0; i < s.size(); i++)
{
if(!st.empty() && st.top() == s[i])
st.pop();
else
st.push(s[i]);
}
string res="";
while(!st.empty())
{
res = st.top() + res;
st.pop();
}
return res;
}
};
150.逆波兰表达式求值
https://leetcode.cn/problems/evaluate-reverse-polish-notation/

class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<long long> st;
for(int i = 0; i < tokens.size(); i++)
{
if(tokens[i]=="+" || tokens[i]=="-" || tokens[i]=="*" || tokens[i]=="/")
{
long long num1 = st.top(); //逆波兰表达式运算符至少在第三个
st.pop();
long long num2 = st.top();
st.pop();
if(tokens[i]=="+") st.push(num1 + num2); //这里需要注意计算顺序。比如10 5 / 先入后出,所以nums2 = 10
if(tokens[i]=="-") st.push(num2 - num1);
if(tokens[i]=="*") st.push(num2 * num1);
if(tokens[i]=="/") st.push(num2 / num1);
}
else st.push(stoll(tokens[i]));
}
return st.top();
}
};
239.滑动窗口求最大值
https://leetcode.cn/problems/sliding-window-maximum/description/

class Solution {
private:
class Myque{
public:
deque<int> q;
void push(int val){
//队列中3 1 2 待入栈val = 5,需要把3 1 2全部出栈
while(!q.empty() && val > q.back())
q.pop_back();
q.push_back(val);
}
void pop(int val){
//比如刚刚那样,队列只有一个5了,就需要跳过两次出栈, 先进入的为front
//一定注意是if!!!!!!!!!!!!!!
if(!q.empty() && val == q.front())
q.pop_front();
}
int max(){
return q.front();
}
};
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
//关键就是没必要挨个push pop 就可以省去比较 比如1 3 -1 就不push1, 具体操作是push 1 -- push 3 (3>1)-- pop 1 -- push -1
//保证push进来的比前面的都大时清空前面小的,前面的小就不动
//这样可以保证队列里每次都是单调递减,不会出现5 2 3 因为push3就会pop2
Myque que;
vector<int> result;
for(int i = 0; i < k; i++)
{
que.push(nums[i]);
}
result.push_back(que.max());
for(int i = k; i < nums.size(); i++)
{
que.pop(nums[i-k]);
que.push(nums[i]);
result.push_back(que.max());
}
return result;
}
};
347.前K个高频元素
https://leetcode.cn/problems/top-k-frequent-elements/description/

class Solution {
public:
class mycmp{
//不要漏掉了public operator后面的() 最后的分号!!!!!!!
public:
bool operator()(pair<int,int> &p1, pair<int,int> &p2){
return p1.second>p2.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
//得到一个nums数组每个元素和出现次数的map
unordered_map<int,int> ump;
for(int i = 0; i < nums.size(); i++)
{
ump[nums[i]]++;
}
//大小顶堆底层都是二叉树,都是从堆顶出栈,不同的是小顶堆顶是最小的,大顶堆顶是最大的,所以用小顶堆,依次把小的都弹出
priority_queue<pair<int,int>, vector<pair<int,int>>, mycmp> pq;
//这里因为要push map里的每个元素,所以要遍历
for(auto it = ump.begin(); it != ump.end(); it++)
{
pq.push(*it);
if(pq.size() > k){
pq.pop();
}
}
vector<int> res;
for(int i = k - 1; i >= 0; i--)
{
res.push_back(pq.top().first);
pq.pop();
}
return res;
}
};


浙公网安备 33010602011771号