当前位置:   article > 正文

算法总结-栈和队列

算法总结-栈和队列

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;i<s.size();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;i<s.size();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<string>& tokens) {
  4. stack<int> sk;
  5. for(int i=0;i<tokens.size();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<k;i++)
  34. {
  35. que.push(nums[i]);
  36. }
  37. result.push_back(que.front());
  38. for(int i=k;i<nums.size();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. //<int,int>
  13. unordered_map<int,int> map;
  14. vector<int> result(k);
  15. for(int i=0;i<nums.size();i++)
  16. {
  17. map[nums[i]]++;
  18. }
  19. priority_queue<pair<int,int>,vector<pair<int,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. };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/789398
推荐阅读
相关标签
  

闽ICP备14008679号