leetcode-栈与队列

  1. C++中stack 是容器么? 栈,队列往往不被归类为容器,而被归类为container adapter(容器适配器)。因为由底层的容器实现,同时使用适配器模式的设计模式,封装了一层。
  • 我们使用的stack是属于哪个版本的STL?SGI STL(linux C++使用的gcc)
  • 我们使用的STL中stack是如何实现的?可以选择容器来实现栈的功能,vector,deque,list 都可以。默认是以deque为缺省情况下栈的底层结构(双向队列,封住一段,只开通另一端)。queue也是。
  • stack ,queue提供迭代器来遍历stack空间么?不提供
  • 1. LeetCode 232. 用栈实现队列 20231020

    一遍过的一题,主要就是模拟一个输入栈,一个输出栈,只有要输出,或者要看顶部的时候才将输入栈里的东西倒到输出栈;还有就是函数名叫empty(),不叫isempty()。还有就是要熟悉栈的操作。还有,写top和pop的时候,top的代码可以复用,不要直接复制过来。

    2. LeetCode 225. 用队列实现栈 20231020

    也是一遍过的题,但是要熟悉队列的操作,比如queue.front(),queue.back().

    我自己写的代码用到了3个queue,而下面的代码仅仅用到了一个queue,且只有一个函数是真正需要做事的,值得学习。

    class MyStack {
    public:
        queue que;
        /** Initialize your data structure here. */
        MyStack() {
    
        }
        /** Push element x onto stack. */
        void push(int x) {
            que.push(x);
        }
        /** Removes the element on top of the stack and returns that element. */
        int pop() {
            int size = que.size();
            size--;
            while (size--) { // 将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部
                que.push(que.front());
                que.pop();
            }
            int result = que.front(); // 此时弹出的元素顺序就是栈的顺序了
            que.pop();
            return result;
        }
    
        /** Get the top element. */
        int top() {
            return que.back();
        }
    
        /** Returns whether the stack is empty. */
        bool empty() {
            return que.empty();
        }
    };

    3.LeetCode 20. 有效的括号 20231020

    今天连做三道简单题,这题卡的最久,久的原因居然是为了调试写了一个stk.top的打印,然后一直没看到这一行,导致疯狂报栈溢出的错。

    这道题也是自己写出来,但是依旧很多需要注意的地方,主要是温习了map的键值对,unordered_map底层的哈希;unordered_map怎么往里面插入数据(insert,或者直接ump[x]=),怎么查找(find、ump[x]),其中还用到一个at(这又是怎么用),这里只用了insert和ump[x]

    class Solution {
    public:
        bool isValid(string s) {
            stack stk;
            unordered_mapump;
            ump.insert({'[',']'});
            ump.insert({'(',')'});
            ump.insert({'{','}'});
            if (s.length()% 2 == 1)     
                return 0;
            for (char i : s){
                if(stk.empty() || ump[stk.top()] != i)
                    stk.push(i);
    
                else
                    stk.pop();
            }
            return stk.empty(); 
        }
    };

    看到别人一个解法,直接省去了我的ump,……

    class Solution {
    public:
        bool isValid(string s) {
            if(s.size()%2) return false;
            stack st;
            for(int i = 0; i < s.size(); ++i){
                if(s[i] == '(')
                    st.push(')');
                else if(s[i] == '{')
                    st.push('}');
                else if(s[i] == '[')
                    st.push(']');
                else if(st.empty() || s[i] != st.top())
                    return false;
                else
                    st.pop();
            }
    
            return st.empty();
        }
    };

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

    又是一道栈的简单题,都没有别的写法,写完就是跟代码随想录一样的。但是依旧有更好的解法,拿字符串直接作为栈(当时写的时候就不想把字符串先变成栈再转换成字符串)。需要熟悉字符串的操作:.empty(),.back(),.pushback(),.pop_back()

    5. LeetCode 150. 逆波兰表达式求值 20231023

    先熟悉一个词:“向零截断”,其实也就是平时计算机处理数据的操作,2.3舍到2,-2.3也是舍到-2,即去掉小数部分。虽然做题没什么用~

    看不起这道中等题,又是常规栈操作,没有什么算法上的难度。

    里面要注意的就是

    1.能合起来写的逻辑就别在if里面写四遍,这里只有num1+-*/num2这个句子要重写。

    2.数据类型转换要注意。隐式转换、强制4种转换还不是很熟悉。有一个stoi,itos,stoll(string to longlong)要注意。这一题因为vector用的是string,导致switch用不了,强转char又难办。

    3.要熟悉int,long,long long的数据长度。

    6. LeetCode 239. 滑动窗口最大值 20231024

    这是一道困难题,其实主要是思路第一次比较难想,我只知道像是用queue做的,但是不知道可以用deque来实现,并且插入删除有一套自己的规则。真正理解起来还是比较容易的。举个例子来看看:

    leetcode-栈与队列_第1张图片

    这里,k=3,所以一开始队列

    push:1,√ 队列:1

    push:3,弹出1,√ 队列:3

    push:-1,√(不因为前面有3就不进-1) 队列:3

    然后往后移动:

    pop:不pop1,因为早已经没了;push:-3 队列:3,-1,-3

    pop:3,因为要push:5,所以还要pop:-1,-3 队列:5

    pop:不pop-1,因为早已经没了;push:3 队列:5,3

    pop:不pop-3,因为早已经没了;因为要push:6,所以还要pop:5,3 队列:6

    pop:不pop5,因为早已经没了;因为要push:7,所以还要pop:6 队列:7

    所以我们要实现的数据结构的三个操作是:

    pop:每一次迭代去pop应该pop的位置上的数,都要pop还存在的数才行,这个就是直接用deque的pop_front

    push:正常进,但是要pop掉前面比它小的数,所以要用到deque的pop_back

    代码也不难,理解以后自己写出来了,其中需要自己定义一个类做新的数据结构。但是,仍然犯了几个小错误。

    class MyQueue{
    public:
        // pop:每一次迭代去pop应该pop的位置上的数,都要pop还存在的数才行,这个就是直接用deque的pop_front
        void pop(int x){
            if(!dq.empty()&&x == dq.front())
                dq.pop_front(); 
        }
        
        // push:正常进,但是要pop掉前面比它小的数,所以要用到deque的pop_back
        void push(int x){
            while(!dq.empty()&&dq.back() < x)//写成了!dq.empty()&&dq.front() < x
                dq.pop_back();//写成了dq.pop_front();
            dq.push_back(x);
        }
        
        int gettop(){
            return dq.front();  
        }
        deque dq;
    
    };
    
    class Solution {
    public:
        MyQueue q;
        vector maxSlidingWindow(vector& nums, int k) {
            vector v1;	
            // 第一轮
            for(int i = 0; i < k; ++i){
                q.push(nums[i]);
            }
            v1.push_back(q.gettop());
            // 之后移动nums.length()-k次:
            for(int i = k; i < nums.size(); ++i){
                q.pop(nums[i - k]);// 错写成nums[i - k - 1]
                q.push(nums[i]);
                v1.push_back(q.gettop());
            }
            return v1;
        }
    };

你可能感兴趣的:(leetcode,leetcode,算法,职场和发展)