首页 > 其他分享 >代码随想录day9-栈和队列1

代码随想录day9-栈和队列1

时间:2024-09-09 19:37:07浏览次数:1  
标签:tmp day9 队列 top 随想录 pop int push empty

题目1 232. 用栈实现队列

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明:

  • 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

示例 1:

输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]

解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false

提示:

  • 1 <= x <= 9
  • 最多调用 100pushpoppeekempty
  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)

进阶:

  • 你能否实现每个操作均摊时间复杂度为 O(1) 的队列?换句话说,执行 n 个操作的总时间复杂度为 O(n) ,即使其中一个操作可能花费较长时间。

思路

这道题的队列实现用两个栈就能解决,一个栈用于模拟入队,另一个栈用于模拟出队。其中一个常规的想法是在pop和peek操作时,先将全部的元素从入队的栈转移到出队的栈,之后取出出队的栈顶部元素,最后将元素从出队栈再放回入队栈里;对上个方法进行优化,可以在出队栈为空时再将元素从入队的栈取出来,这样可以节省一部分时间。

代码1

class MyQueue {
    stack<int> stack1,
               stack2;
public:
    MyQueue() {

    }
    
    void push(int x) {
        stack1.push(x);
    }
    
    int pop() {
        while(stack1.size() != 1)
        {
            int tmp = stack1.top();
            stack2.push(tmp);
            stack1.pop();
        }
        int tmp = stack1.top();
        stack1.pop();
        while(stack2.size() != 0)
        {
            int tmp = stack2.top();
            stack1.push(tmp);
            stack2.pop();
        }
        return tmp;
    }
    
    int peek() {
        while(stack1.size() != 1)
        {
            stack2.push(stack1.top());
            stack1.pop();
        }
        int tmp = stack1.top();
        while(stack2.size() != 0)
        {
            stack1.push(stack2.top());
            stack2.pop();
        }
        return tmp;
    }
    
    bool empty() {
        return stack1.size() == 0;
    }
};

/**
 * 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();
 */

代码2 优化

class MyQueue {
    stack<int> stack1,
               stack2;
public:
    MyQueue() {

    }
    
    void push(int x) {
        stack1.push(x);
    }
    
    int pop() {
        if(stack2.empty())
            while(stack1.size() != 0)
            {
                int tmp = stack1.top();
                stack2.push(tmp);
                stack1.pop();
            }
        int tmp = stack2.top();
        stack2.pop();
        return tmp;
    }
    
    int peek() {
        int tmp = this->pop();
        stack2.push(tmp);
        return tmp;
    }
    
    bool empty() {
        return stack1.size() == 0 && stack2.size() == 0;
    }
};

/**
 * 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();
 */

题目2 225. 用队列实现栈

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppopempty)。

实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false

注意:

  • 你只能使用队列的标准操作 —— 也就是 push to backpeek/pop from frontsizeis empty 这些操作。
  • 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

示例:

输入:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]

解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False

思路

这道题用队列模拟栈的操作,我使用的时单队列queue,要注意的就是pop操作消耗的时间较多。

代码

class MyStack {
    queue<int> myQueue;
public:
    MyStack() {

    }
    
    void push(int x) {
        myQueue.push(x);
    }
    
    int pop() {
        int tmp = myQueue.back();
        int size = myQueue.size();
        while(--size > 0)
        {
            myQueue.push(myQueue.front());
            myQueue.pop();
        }
        myQueue.pop();
        return tmp;
    }
    
    int top() {
        return myQueue.back();
    }
    
    bool empty() {
        return myQueue.empty();
    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */

题目3 20. 有效的括号

给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例 1:

输入:s = "()"

输出:true

示例 2:

输入:s = "()[]{}"

输出:true

示例 3:

输入:s = "(]"

输出:false

示例 4:

输入:s = "([])"

输出:true

提示:

  • 1 <= s.length <= 104
  • s 仅由括号 '()[]{}' 组成

思路

用一个额外的栈存储左括号,当处理字符为右括号字符时判断栈是否为空并且与栈top的元素进行匹配,当全部元素匹配成功后返回true,当匹配失败或处理最后栈不为空则返回false

代码

class Solution {
public:
    bool isValid(string s) {
        if(s.size() == 1 || s.size() % 2 == 1)
        {
            return false;
        }
        stack<char> judgeStack;
        char tmp;
        for(auto &c: s)
        {
            switch(c)
            {
#define INSTACK(STACK, CASE) case CASE: \
                                STACK.push(CASE);\
                                break;
            INSTACK(judgeStack, '(');
            INSTACK(judgeStack, '{');
            INSTACK(judgeStack, '[');
#undef INSTACK
#define OUTSTACK(STACK, CASE, COND) case CASE: \
                                        if(STACK.empty()) return false;\
                                        tmp = STACK.top(); \
                                        STACK.pop();            \
                                        if(tmp == COND) break;  \
                                        else            return false;
    
            OUTSTACK(judgeStack, ')' ,'(');
            OUTSTACK(judgeStack, '}', '{');
            OUTSTACK(judgeStack, ']', '[');
#undef OUTSTACK
            }
        }
        return judgeStack.empty();
    }
};

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

给出由小写字母组成的字符串 s重复项删除操作会选择两个相邻且相同的字母,并删除它们。

s 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

示例:

输入:"abbaca"
输出:"ca"
解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。

提示:

  1. 1 <= s.length <= 105
  2. s 仅由小写英文字母组成。

思路

这道题用栈解决,碰到一个字符先判断栈是否为空或者不等于栈top的元素,若满足条件则入栈,不满足条件则pop栈top的元素。

代码

class Solution {
public:
    string removeDuplicates(string s) {
        if(s.size() == 1)
            return s;
        stack<char> deplStack;
        char tmp;
        for(auto &c : s)
        {
            if(deplStack.empty() || c != deplStack.top())
            {
                deplStack.push(c);
            }
            else
            {
                deplStack.pop();
            }
        }
        string result;
        result.reserve(deplStack.size());
        while(!deplStack.empty())
        {
            result += deplStack.top();
            deplStack.pop();
        }
        reverse(result.begin(), result.end());
        return move(result);
    }
};

标签:tmp,day9,队列,top,随想录,pop,int,push,empty
From: https://www.cnblogs.com/code4log/p/18405155

相关文章

  • 单生产者单消费者无锁队列
    单生产者单消费者无锁队列伪共享:下图是计算的基本结构。L1、L2、L3分别表示一级缓存、二级缓存、三级缓存,越靠近CPU的缓存,速度越快,容量也越小。所以L1缓存很小但很快,并且紧靠着在使用它的CPU内核;L2大一些,也慢一些,并且仍然只能被一个单独的CPU核使用;L3更大、更慢,并且被单个插槽上......
  • 代码随想录day8-字符串2
    题目1151.反转字符串中的单词*给你一个字符串s,请你反转字符串中单词的顺序。单词是由非空格字符组成的字符串。s中使用至少一个空格将字符串中的单词分隔开。返回单词顺序颠倒且单词之间用单个空格连接的结果字符串。注意:输入字符串s中可能会存在前导空格、尾......
  • 洛谷题单指南-常见优化技巧-P1886 滑动窗口 /【模板】单调队列
    原题链接:https://www.luogu.com.cn/problem/P1886题意解读:单调队列模版题。解题思路:采用双端队列维护单调的序列,单调队列三部曲:1、去头,当窗口内元素个数超过k,队头出队2、去尾,当要加入的元素会破坏单调性,队尾出队3、入队,将元素的下标存入队列每一次入队后,队头元素即为窗口最......
  • 代码随想录day55 || 图论5
    并查集197图中是否存在有效路径varfather[]intfuncvalidPath(nint,edges[][]int,sourceint,destinationint)bool{ //使用并查集算法,涉及到的操作,包括init,find,issample,join father=make([]int,n) fori,_:=rangefather{//init father[i]=i }......
  • 多线程篇(阻塞队列- DelayQueue)(持续更新迭代)
    目录一、简介二、基本原理四、代码示例简单定时调度任务多消费者定时调度任务得出结论四、应用场景一、简介DelayQueue是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。这种队列是有序的,即队头对象的延迟到......
  • 多线程篇(阻塞队列- PriorityBlockingQueue)(持续更新迭代)
    目录一、简介二、类图三、源码解析1.字段讲解2.构造方法3.入队方法put浮调整比较器方法的实现入队图解4.出队方法takedequeue下沉调整比较器方法的实现出队图解四、总结一、简介PriorityBlockingQueue队列是JDK1.5的时候出来的一个阻塞队列。但是该队......
  • 网安实习Day9@^@
    一、阿里云服务器安装CobaltStrike4.8(一)下载cs4.8压缩包解压在本地(二)使用xftp上传到阿里云服务器(三)xshell连接服务器进入到/CobalStrike4.8/Server/(四)对teamserver和TeamServerImage添加可执行权限命令:chmod+xteamserver  chmod+xTeamServerImage(五)运行团队服......
  • 【算法笔记】单源最短路问题——Dijkstra算法(无优化/优先队列/set优化)
    0.前言Dijkstra算法可在\(\mathcalO(m\logm)\)或\(\mathcalO(m\logn)\)的时间内求解无负权单源最短路问题。本文中,我们将详细介绍算法的原理、实现,以及常用的两种优化。另外,Dijkstra算法也不要乱用,比如说多源的最短路,用Dijkstra求解的复杂度只有\(\mathcalO(nm\logm)\),但......
  • Redis 实现延迟队列的巧妙方法
    今天我们来探索一下Redis是如何巧妙地实现延迟队列的,这可是在很多场景下都非常实用的技术哦!一、什么是延迟队列?延迟队列,简单来说,就是可以让消息在指定的延迟时间之后才被消费的队列。想象一下,你在网上订了一份外卖,商家并不会立即配送,而是根据你选择的送达时间,延迟一段时......
  • 【数据结构】栈与队列OJ题(用队列实现栈)(用栈实现队列)
    目录1.用队列实现栈oj题对比一、初始化二、出栈 三、入栈四、取队头元素:2.用栈实现队列 一、定义二、入队列三、出队列四、队头五、判空                                      ......