【打卡】——【LeetCode学习计划】《数据结构入门-C++》第9天 栈 / 队列

原文链接:【LeetCode学习计划】《数据结构入门-C++》第9天 栈 / 队列_Wang_Xin_Ling的博客-CSDN博客

目录

20. 有效的括号LeetCode: 20. 有效的括号

方法1:栈

栈的基本知识数据结构——栈的详解_ACfun-CSDN博客_数据结构栈

入栈

出栈

232. 用栈实现队列LeetCode: 232. 用栈实现队列

方法1:(使用两个栈 入队 - O(n), 出队 - O(1))

入队(push)

判断空(empty)

完整代码 


20. 有效的括号
LeetCode: 20. 有效的括号

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

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
 

方法1:栈

栈的基本知识数据结构——栈的详解_ACfun-CSDN博客_数据结构栈


我们可以先跳过对于左括号的思考。假设我们能够记录所有的左括号,那么我们每次遇到右括号时的操作就是取出最后一个记录的左括号,然后判断是否能匹配。所以这是一个先入后出的情景,也正是栈的特点。

当遇到右括号时,取出栈顶,如果匹配则继续,不匹配则直接返回假值
当然,取栈顶的时候有可能栈为空,此时代表不匹配,返回假值
如果遍历结束后栈不为空,说明左括号冗余,也返回假值
同时,有效的括号必然成对出现,这也意味着正确的字符串起码也得是偶数长度,因此奇数长度的字符串就不用操作了,直接返回假值

后进先出
栈的示意图

基本知识:数据结构——栈的详解_ACfun-CSDN博客_数据结构栈

#include <string>
#include <stack>
using namespace std;
class Solution
{
public:
    bool isValid(string s)
    {
        if (s.length() % 2 == 1)
            return false;

        stack<char> stk;
        for (const auto &c : s)
        {
            switch (c)
            {
            case '(':
            case '[':
            case '{':
                stk.push(c);
                break;

            case ')':
            {
                if (stk.empty() || stk.top() != '(')
                    return false;
                stk.pop();
                break;
            }
            case ']':
            {
                if (stk.empty() || stk.top() != '[')
                    return false;
                stk.pop();
                break;
            }
            case '}':
            {
                if (stk.empty() || stk.top() != '{')
                    return false;
                stk.pop();
                break;
            }
            }
        }
        return stk.empty();
    }
};

入栈

使用push()函数来完成入栈操作。

出栈

使用pop()函数实现出栈

232. 用栈实现队列
LeetCode: 232. 用栈实现队列

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
 

前言
队列是一种先进先出(First In First Out, FIFO)的数据结构,元素从队尾入队,从队首出队。大家最熟悉的可能就是各种输入输出流,比如标准输入输出流std:cin和std::cout就是典型的FIFO。

栈是一种后进先出(Last In First Out, LIFO)的数据结构,元素从栈顶压入,也从栈顶弹出。

为了满足队列FIFO的特性,我们需要用到2个栈。

方法1:(使用两个栈 入队 - O(n), 出队 - O(1))



入队(push)

1) 

  1. 也就是说压入元素时,我们需要把当前栈内所有的元素依次弹出压入另一个栈中;
  2. 然后才能压入新元素,这样新元素就会变成最后出队;
  3. 最后再将所有元素压回来。
class MyQueue {
private:
    stack<int> inStack, outStack;

    void in2out() {
        while (!inStack.empty()) {
            outStack.push(inStack.top());
            inStack.pop();
        }
    }

public:
    MyQueue() {}

    void push(int x) {
        inStack.push(x);
    }

2).直接将栈顶元素弹出即可

int pop() {
        if (outStack.empty()) {
            in2out();
        }
        int x = outStack.top();
        outStack.pop();
        return x;
    }

3)返回栈顶元素即可 

int peek() {
        if (outStack.empty()) {
            in2out();
        }
        return outStack.top();
    }

判断空(empty)

栈空即代表队列空,判断栈是否为空即可。

bool empty() {
        return inStack.empty() && outStack.empty();
    }

完整代码 

class MyQueue {
private:
    stack<int> inStack, outStack;

    void in2out() {
        while (!inStack.empty()) {
            outStack.push(inStack.top());
            inStack.pop();
        }
    }

public:
    MyQueue() {}

    void push(int x) {
        inStack.push(x);
    }

    int pop() {
        if (outStack.empty()) {
            in2out();
        }
        int x = outStack.top();
        outStack.pop();
        return x;
    }

    int peek() {
        if (outStack.empty()) {
            in2out();
        }
        return outStack.top();
    }

    bool empty() {
        return inStack.empty() && outStack.empty();
    }
};

 

Guess you like

Origin blog.csdn.net/qq_62932195/article/details/121970735