• 算法总结-栈和队列


    1.栈实现队列

    思路:两个栈实现,一个出一个进。

    pop() 把sin的元素出栈赋值给sout,赋值完后sout pop的第一个就是队头元素

    peek() 直接调用上述实现的pop函数 

    1. class MyQueue {
    2. public:
    3. MyQueue() {
    4. }
    5. stack<int> sin;
    6. stack<int> sout;
    7. void push(int x) {
    8. sin.push(x);
    9. }
    10. int pop() {
    11. if(sout.empty())
    12. {
    13. while(!sin.empty())
    14. {
    15. sout.push(sin.top());
    16. sin.pop();
    17. }
    18. }
    19. int res=sout.top();
    20. sout.pop();
    21. //两个栈实现 弹出后另外一个栈不需要赋值了 后续直接用sout操作
    22. return res;
    23. }
    24. int peek() {
    25. int res=this->pop();
    26. //这里是sout再push进来
    27. sout.push(res);
    28. return res;
    29. }
    30. bool empty() {
    31. return sin.empty()&&sout.empty();
    32. }
    33. };

    2.队列实现栈

    思路:单个队列实现。

    pop:把队列的头元素依次插入到队尾,除了最后一个(这个元素是要pop出去的)。

    top:直接调用队列的back方法

    1. class MyStack {
    2. public:
    3. MyStack() {
    4. }
    5. queue<int> q1;
    6. void push(int x) {
    7. q1.push(x);
    8. }
    9. int pop() {
    10. int size=q1.size();
    11. size--;
    12. while(size--)
    13. {
    14. q1.push(q1.front());
    15. q1.pop();
    16. }
    17. int res=q1.front();
    18. //记得要pop
    19. q1.pop();
    20. return res;
    21. }
    22. int top() {
    23. int res=q1.back();
    24. return res;
    25. }
    26. bool empty() {
    27. return q1.empty();
    28. }
    29. };

     20. 有效的括号

    思路:用栈来实现,遍历s对于每一个左括号,栈里push进一个相应的右括号。两种失败情况,如果栈的top和s[i]相等就返回true

    1. class Solution {
    2. public:
    3. bool isValid(string s) {
    4. stack<char> sk;
    5. for(int i=0;isize();i++)
    6. {
    7. if(s[i]=='(')
    8. {
    9. sk.push(')');
    10. }
    11. else if(s[i]=='[')
    12. {
    13. sk.push(']');
    14. }
    15. else if(s[i]=='{')
    16. {
    17. sk.push('}');
    18. }
    19. // 第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号 return false
    20. // 第二种情况:遍历字符串匹配的过程中,发现栈里没有我们要匹配的字符。所以return false
    21. else if(sk.empty()||sk.top()!=s[i])
    22. {
    23. return false;
    24. }
    25. else
    26. {
    27. //sk.top()==s[i] 栈弹出
    28. sk.pop();
    29. }
    30. }
    31. return sk.empty();
    32. }
    33. };

    1047. 删除字符串中的所有相邻重复项

    注意 push的逻辑

    1. class Solution {
    2. public:
    3. string removeDuplicates(string s) {
    4. stack<char> sk;
    5. for(int i=0;isize();i++)
    6. {
    7. //注意 push的逻辑
    8. if(sk.empty()||sk.top()!=s[i])
    9. {
    10. sk.push(s[i]);
    11. }
    12. else{
    13. sk.pop();
    14. }
    15. }
    16. string res="";
    17. while(!sk.empty())
    18. {
    19. res+=sk.top();
    20. sk.pop();
    21. }
    22. reverse(res.begin(),res.end());
    23. return res;
    24. }
    25. };

    150. 逆波兰表达式求值

    用2 减去 1 

    要用stoll把string转成int

    1. class Solution {
    2. public:
    3. int evalRPN(vector& tokens) {
    4. stack<int> sk;
    5. for(int i=0;isize();i++)
    6. {
    7. if(tokens[i]=="+"||tokens[i]=="-"||tokens[i]=="*"||tokens[i]=="/")
    8. {
    9. int num1=sk.top();
    10. sk.pop();
    11. int num2=sk.top();
    12. //这里也要pop掉
    13. sk.pop();
    14. if(tokens[i]=="+")
    15. sk.push(num2+num1);
    16. if(tokens[i]=="-")
    17. sk.push(num2-num1);
    18. if(tokens[i]=="*")
    19. sk.push(num2*num1);
    20. if(tokens[i]=="/")
    21. sk.push(num2/num1);
    22. }
    23. else{
    24. //字符串要转成 int
    25. sk.push(stoll(tokens[i]));
    26. }
    27. }
    28. return sk.top();
    29. }
    30. };

    239. 滑动窗口最大值

    deque双端队列 

    思路 用deque模拟滑动窗口动,封装好pop、push、front方法

    1. class Solution {
    2. public:
    3. class Mydeque
    4. {
    5. public:
    6. deque<int> de;
    7. void pop(int value)
    8. {
    9. //窗口移除的元素是第一个元素 那么pop 其他的都不操作
    10. if(!de.empty()&&value==de.front())
    11. {
    12. de.pop_front();
    13. }
    14. }
    15. void push(int value)
    16. {
    17. //先pop 循环判断 值大于最后一个值就pop
    18. while(!de.empty() &&value>de.back())
    19. {
    20. de.pop_back();
    21. }
    22. //再push
    23. de.push_back(value);
    24. }
    25. int front()
    26. {
    27. return de.front();
    28. }
    29. };
    30. vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    31. Mydeque que;
    32. vector<int> result;
    33. for(int i=0;i
    34. {
    35. que.push(nums[i]);
    36. }
    37. result.push_back(que.front());
    38. for(int i=k;isize();i++)
    39. {
    40. que.pop(nums[i-k]);
    41. que.push(nums[i]);
    42. result.push_back(que.front());
    43. }
    44. return result;
    45. }
    46. };

    347. 前 K 个高频元素 

    小顶堆队列

    先用哈希map存储每个元素的频率

    放入队列中 控制队列大小

    小顶堆=>反向输出到结果集

    1. class Solution {
    2. public:
    3. class mycmp{
    4. // public:
    5. public:
    6. bool operator ()(const pair<int,int> &lhs,const pair<int,int> &rhs)
    7. {
    8. return lhs.second>rhs.second;
    9. }
    10. };
    11. vector<int> topKFrequent(vector<int>& nums, int k) {
    12. //
    13. unordered_map<int,int> map;
    14. vector<int> result(k);
    15. for(int i=0;isize();i++)
    16. {
    17. map[nums[i]]++;
    18. }
    19. priority_queueint,int>,vectorint,int>>,mycmp> pri_que;
    20. for(unordered_map<int,int>:: iterator it=map.begin();it!=map.end();it++)
    21. {
    22. pri_que.push(*it);
    23. if(pri_que.size()>k)
    24. {
    25. pri_que.pop();
    26. }
    27. }
    28. for(int i=k-1;i>=0;i--)
    29. {
    30. //pri_que.top().first;
    31. result[i]=pri_que.top().first;
    32. pri_que.pop();
    33. }
    34. return result;
    35. }
    36. };

  • 相关阅读:
    22年第二批次PMP考试倒计时9天
    【LeetCode刷题笔记】链表
    编程随笔-Java | 04.栈Stack、队列Queue和双端队列Deque
    javaEE进阶 - Spring 更简单的读取和存储对象 - 细节狂魔
    B. Kalindrome Array
    C++每日面试之struct 和 class
    嵌入式系统在物联网中的应用和发展
    k8s nfs-client 添加挂载参数 —— 筑梦之路
    提升资源利用率与保障服务质量,鱼与熊掌不可兼得?
    Adobe Acrobat Reader界面改版 - 解决方案
  • 原文地址:https://blog.csdn.net/qq_66230764/article/details/139768264