Leetcode 栈&队列

Pre

  • 先进后出(FILO)
  • 线性表
  • push & pop
//栈的基本操作
stack.push()
stack.pop()
stack.size()
stack.empty()
stack.top()
//EXAMPLE
#include <iostream>
#include <stack>
using namespace std;

int main(){
    stack<int> S;
    if(S.empty()){
        cout<<"S is empty"<<endl;
    }
    S.push(5);
    S.push(6);
    S.push(10);
    cout<<"The top of S is "<<S.top()<<endl;
    S.pop();
    S.push(1);
    cout<<"The size of S is "<<S.size()<<endl;
    return 0;
}
  • 注意栈和队列随着push&pop操作,size会随之变化

from 155.cpp

int length=_data.size();
        for(int i=0; i<length;i++){
            int x=_data.top();
            temp_data.push(x);
            _data.pop();
            if(x<min){
                min=x;
            }
        }
        for(int i=0;i<length;i++){
            int x=temp_data.top();
            _data.push(x);
            temp_data.pop();
        }

队列

  • 先进先出(FIFO)
  • 线性表
  • push & pop
queue.empty()
queue.push()
queue.pop()
queue.size()
queue.front()
queue.back()
#include <iostream>
#include <queue>
using namespace std;

int main(){
    queue<int> Q;
    if(Q.empty()){
        cout<<"Q is empty"<<endl;
    }
    Q.push(5);
    Q.push(6);
    Q.push(10);
    cout<<"The front of Q is "<<Q.front()<<endl;
    Q.pop();
    Q.pop();
    cout<<"The front of Q is "<<Q.front()<<endl;
    Q.push(1);
    cout<<"The back of Q is "<<Q.back()<<endl;
    cout<<"The size of Q is "<<Q.size()<<endl;
    return 0;
}
  • 字符串处理
    • 方法: 状态机
    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j4qrObW7-1614946892899)(./STATE_MACHINE.png)]
    • 状态转换时, 字符指针i退格

  • 二叉堆
    • 最大(小)值先出的完全二叉树
    • 调整,删除 O(log(N))
    • 最大堆
      • 左右子树分别是最大堆
    • 最小堆
  • STL优先级队列
priority_queue<int> big_heap; //O(n)
priority_queue<int, vector<int>, std::greater<int>> small_heap; 
heap.empty()
heap.pop() //时间复杂度: O(logN)
heap.push(x)
heap.top() //时间复杂度: O(1)
heap.size()

题目

20. 有效的括号(Easy)

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

有效字符串需满足:

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

示例 1:
输入:s = “()”
输出:true
示例 2:
输入:s = “()[]{}”
输出:true
示例 3:
输入:s = “(]”
输出:false
示例 4:
输入:s = “([)]”
输出:false
示例 5:
输入:s = “{[]}”
输出:true

提示:

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

class Solution {
public:
    bool isValid(string s) {
        if(s.size()%2==1){
            return false;
        }

        stack<char> S;

        for(auto i:s){
            switch(i){
                case '(': case '{' : case '[':
                    S.push(i);
                    break;
                case ')':
                    if(!S.empty() && S.top()=='('){
                        S.pop();
                    }else{
                        return false;
                    }
                    break;
                case '}':
                    if(!S.empty() && S.top()=='{'){
                        S.pop();
                    }else{
                        return false;
                    }
                    break;
                case ']':
                    if(!S.empty()&&S.top()=='['){
                        S.pop();
                    }else{
                        return false;
                    }
                    break;
            }
        }
        if(S.empty()){
            return true;
        }else{
            return false;
        }
    }
};

155. 最小栈(Easy)

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。

示例:
输入:
[“MinStack”,“push”,“push”,“push”,“getMin”,“pop”,“top”,“getMin”]
[[],[-2],[0],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,0,-2]
解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.

提示:

pop、top 和 getMin 操作总是在 非空栈 上调用。

#include <stack>
using std::stack;
class MinStack {
public:
    /** initialize your data structure here. */
    MinStack() {
    }
    
    void push(int x) {
        _data.push(x);
        if(min_data.empty()){
            min_data.push(x);
        }else{
            int y=min_data.top();
            if(x<y){
                min_data.push(x);
            }else{
                min_data.push(y);
            }
        }

        
    }
    
    void pop() {
        _data.pop();
        min_data.pop();
        
    }
    
    int top() {
        int y=_data.top();
        return y;
        
    }
    
    int getMin() {
        int y=min_data.top();
        return y;
        
    }
private:
    stack<int> _data;
    stack<int> min_data;
};

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


215. 数组中的第K个最大元素(Medium)

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

说明:

你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int, vector<int>, std::greater<int>> small_heap;
        for(int i=0;i<k;i++){
            small_heap.push(nums[i]);
        }
        for(int i=k;i<nums.size();i++){
            if(nums[i]>small_heap.top()){
                small_heap.pop();
                small_heap.push(nums[i]);
            }
        }
        return small_heap.top();
    }

225. 用队列实现栈(Easy)

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

实现 MyStack 类:

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

注意:

你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is 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

提示:

1 <= x <= 9
最多调用100 次 push、pop、top 和 empty
每次调用 pop 和 top 都保证栈不为空

进阶:你能否实现每种操作的均摊时间复杂度为 O(1) 的栈?换句话说,执行 n 个操作的总时间复杂度 O(n) ,尽管其中某个操作可能需要比其他操作更长的时间。你可以使用两个以上的队列。

class MyStack {
public:
    /** Initialize your data structure here. */
    
    MyStack() {
    }
    
    /** Push element x onto stack. */
    void push(int x) {
        queue<int> temp_queue;
        temp_queue.push(x);
        while(!_data.empty()){
            int y=_data.front();
            temp_queue.push(y);
            _data.pop();
        }
        while(!temp_queue.empty()){
            int y=temp_queue.front();
            _data.push(y);
            temp_queue.pop();
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int y=_data.front();
        _data.pop();
        return y;
    }
    
    /** Get the top element. */
    int top() {
        return _data.front();
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
        return _data.empty();
    }
    private:
        queue<int> _data;
};

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

232. 用栈实现队列(Easy)

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

实现 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(双端队列)来模拟一个栈,只要是标准的栈操作即可。

进阶:

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

示例:
输入:
[“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
最多调用 100 次 push、pop、peek 和 empty
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)

class MyQueue {
public:
    /** Initialize your data structure here. */
    MyQueue() {

    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
        stack<int> temp_data;
        while(!_data.empty()){
            int y=_data.top();
            temp_data.push(y);
            _data.pop();
        }
        temp_data.push(x);
        while(!temp_data.empty()){
            int y=temp_data.top();
            _data.push(y);
            temp_data.pop();
        }

    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        int y=_data.top();
        _data.pop();
        return y;

    }
    
    /** Get the front element. */
    int peek() {
        int y=_data.top();
        return y;

    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        return _data.empty();

    }
private:
    stack<int> _data;
};

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


946. 验证栈序列(Medium)

给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false 。

示例 1:
输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
示例 2:
输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。

提示:

0 <= pushed.length == popped.length <= 1000
0 <= pushed[i], popped[i] < 1000
pushed 是 popped 的排列。

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        int size = pushed.size();
        stack<int> S;
        int j=0;
        for(int i=0;i<size;i++){
            S.push(pushed[i]);
            while(!S.empty()&&S.top()==popped[j]){
                S.pop();
                j++;

            }
        }
        if(S.empty()){
            return true;
        }else{
            return false;
        }
    }
};

(POJ)1363. Rails

Description

There is a famous railway station in PopPush City. Country there is incredibly hilly. The station was built in last century. Unfortunately, funds were extremely limited that time. It was possible to establish only a surface track. Moreover, it turned out that the station could be only a dead-end one (see picture) and due to lack of available space it could have only one track.
The local tradition is that every train arriving from the direction A continues in the direction B with coaches reorganized in some way. Assume that the train arriving from the direction A has N <= 1000 coaches numbered in increasing order 1, 2, …, N. The chief for train reorganizations must know whether it is possible to marshal coaches continuing in the direction B so that their order will be a1, a2, …, aN. Help him and write a program that decides whether it is possible to get the required order of coaches. You can assume that single coaches can be disconnected from the train before they enter the station and that they can move themselves until they are on the track in the direction B. You can also suppose that at any time there can be located as many coaches as necessary in the station. But once a coach has entered the station it cannot return to the track in the direction A and also once it has left the station in the direction B it cannot return back to the station.

Input

The input consists of blocks of lines. Each block except the last describes one train and possibly more requirements for its reorganization. In the first line of the block there is the integer N described above. In each of the next lines of the block there is a permutation of 1, 2, …, N. The last line of the block contains just 0.

The last block consists of just one line containing 0.
Output

The output contains the lines corresponding to the lines with permutations in the input. A line of the output contains Yes if it is possible to marshal the coaches in the order required on the corresponding line of the input. Otherwise it contains No. In addition, there is one empty line after the lines corresponding to one block of the input. There is no line in the output corresponding to the last ``null’’ block of the input.
Sample Input

5
1 2 3 4 5
5 4 1 2 3
0
6
6 5 4 3 2 1
0
0
Sample Output

Yes
No

Yes

bool check_is_valid_order(queue<int> &order){
    stack<int> S;
    int size=order.size();
    for(int i=1;i<=size;i++){
        S.push(i);
        while(order.front()==S.top()$$!S.empty()){
            S.pop();
            order.pop();
        }
    }
    if(S.empty()){
        return true;
    }else{
        return false;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值