算法-栈,队列

常见的栈与队列算法题

1.使用队列实现栈

2.使用栈实现队列

3.包含最小值函数的栈

4.合法的出栈序列

5.简单计算器



1.队列实现栈

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

    }

    /** Push element x onto stack. */
    void push(int x) {
        int len=data.size();
        data.push(x);
        while(len>0){
            data.push(data.front());
            data.pop();
            len--;
        }
    }

    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int res=data.front();
        data.pop();
        return res;

    }

    /** Get the top element. */
    int top() {
        return data.front();
    }

    /** Returns whether the stack is empty. */
    bool empty() {
        return data.empty();
    }
private:
    std::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();
 */

主要是push函数的编写。x进队后,让之前的元素 一 一 出队再入队。



2.栈实现队列

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

    }

    /** Push element x to the back of queue. */
    void push(int x) {
        while(s.size()){
            s_temp.push(s.top());
            s.pop();
        }
        s.push(x);
        while(s_temp.size()){
            s.push(s_temp.top());
            s_temp.pop();
        }
    }

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

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

    /** Returns whether the queue is empty. */
    bool empty() {
        return s.empty();
    }
private:
    std::stack<int> s,s_temp;
};

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

缺点是,入队所需时间太长,操作步数为2n步。其他为常数。

改进

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

    }
    void transfer(){
        while(!in.empty()){
            out.push(in.top());
            in.pop();
        }
    }
    /** Push element x to the back of queue. */
    void push(int x) {
        in.push(x);
    }

    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        int res=peek();
        out.pop();
        return res;
    }

    /** Get the front element. */
    int peek() {
        if(out.size()==0)
            transfer();
        return out.top();
    }

    /** Returns whether the queue is empty. */
    bool empty() {
        return (in.empty() && out.empty());
    }
private:
    std::stack<int> in,out;
};

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

pop和peek平均都为n/2步,总步数n步。略微简化了一些。



3.最小值栈

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

  • push(x) -- 将元素 x 推入栈中。
  • pop() -- 删除栈顶的元素。
  • top() -- 获取栈顶元素。
  • getMin() -- 检索栈中的最小元素。
class MinStack {
public:
    /** initialize your data structure here. */
    MinStack() {

    }

    void push(int x) {
        s.push(x);
        if(sMin.empty() || x <= sMin.top()){
            sMin.push(x);
        }
    }

    void pop() {
        if(s.top()==sMin.top()){
            s.pop();
            sMin.pop();
        }else{
            s.pop();
        }
    }

    int top() {
        return s.top();
    }

    int getMin() {
        return sMin.top();
    }
private:
    std::stack<int> s,sMin;
};

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

用另一个栈sMin记录最小值。空间复杂度O(n).



4.合法的出栈序列

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

        }
        return s.empty();
    }
};

借助一个栈s,模拟进出栈顺序。遍历pushed数组,先将元素进栈。然后再开一个出栈循环,若栈不空,将栈顶与popped数组元素比较,相同则出栈,继续下一个循环;不同则跳出出栈循环,继续外面的进栈操作。最后返回是否栈空。以上应该是最为清晰的思路了,之前我也写过两个,一个暴力法判断,时间复杂度较高,逻辑也很复杂;另一个也是模拟进出栈,但是思路太乱,代码逻辑冗余混乱,简单来说就是模拟的不够真实,反而导致自己思路不畅。



5.简单计算器

实现一个基本的计算器来计算一个简单的字符串表达式的值。

字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -非负整数和空格

class Solution {
public:
    int calculate(string s) {
        int len = s.length();
        if (len == 0) return 0;//长度为0直接返回0
        int num1 = 0, num2 = 0;//存储运算数
        bool flag = false;//是否能进行运算
        stack<int> num;//数字栈
        stack<char> op;//运算符栈
        int temp = 0;//存储数字
        for (int i = 0; i < len; i++) {
            if (s[i] == ‘ ‘) continue;
            if (s[i] >= ‘0‘ && s[i] <= ‘9‘) {
                temp = temp * 10 + s[i] - ‘0‘;
                if (i + 1 == len || s[i + 1]<‘0‘ || s[i + 1]>‘9‘) {
                    num.push(temp);
                    temp = 0;//清0
                }else {
                    continue;//继续入栈求该数字
                }
            }else if (s[i] == ‘(‘) {
                flag = false;//设置无法运算
                continue;
            }else if (s[i] == ‘+‘ || s[i] == ‘-‘) {
                op.push(s[i]);
                flag = true;//可以运算
                continue;
            }else if(s[i]==‘)‘){
                flag = true;//可以运算
            }

            if (flag && !op.empty()) {    //运算栈不为空才可以运算
                num2 = num.top(); num.pop();
                num1 = num.top(); num.pop();
                if (op.top() == ‘+‘) {
                    num.push(num1 + num2);
                }
                else {
                    num.push(num1 - num2);
                }
            op.pop();//不要忘记出栈
            }
        }
        return num.top();
    }
};

重点在于flag,表示是否能进行运算。数字入数字栈,运算符入运算符栈,且设flag=true。左括号使得flag=false,右括号使得false=true。flag为true且运算栈不为空则进行运算,运算完不要忘记出栈

原文地址:https://www.cnblogs.com/chendaniu/p/10235484.html

时间: 2024-10-08 02:15:00

算法-栈,队列的相关文章

数据结构与算法--栈、队列(队列)

Hello,everybody.我们又见面了.今天我们来学习一下队列这个数据结构,let's Go,开始我们的征程吧. 首先,举两个生活中的常见例子.相信大家,在用电脑工作娱乐时,都会碰到这样的现象.当我们点击程序或进行其他操作时,电脑处于死机状态.正当我们准备Reset时,它突然像打了鸡血似的,突然把刚才我们的操作,按顺序执行了一遍.之所以会出现这个现象,是因为操作系统的多个程序,需要通过一个管道输出,而按先后顺序排队造成的. 还有有个例子,在我们打客服热线时,有时会出现等待的现象.当其他客户

【C/C++学院】0828-STL入门与简介/STL容器概念/容器迭代器仿函数算法STL概念例子/栈队列双端队列优先队列/数据结构堆的概念/红黑树容器

STL入门与简介 #include<iostream> #include <vector>//容器 #include<array>//数组 #include <algorithm>//算法 using namespace std; //实现一个类模板,专门实现打印的功能 template<class T> //类模板实现了方法 class myvectorprint { public: void operator ()(const T &

&lt;数据结构与算法分析 C++描述&gt; 表/栈/队列

这一章主要内容: * 抽象数据类型(ADT)的概念 * 实现表/栈/队列 * 了解这三个数据结构的应用场景 1. ADT ADT: abstract data type, 是抽象的数学模型,在该模型上定义了一系列的操作.使用它的人,不需要了解它的存储方式,只关心它的逻辑特征.可以使用三元组的方法来表示(D,S,P),D是数据对象,S是数据之间的关系,P是对数据的基本操作,具体介绍,可以参考帖子:点击打开链接 2. 表ADT 表的数据自然是单个元素,而元素之间的关系是前驱与后继,操作包括查找/插入

栈&队列的简单实现

栈的定义---Stack 栈只允许在栈的末端进行插入和删除的线性表.栈具有先进后出的特性. 栈可用顺序表实现也可用链表实现. 但: 由于栈只能在末端进行操作,应使用顺序表实现. 用顺序表实现,有如下优点: (1)方便管理 (2)效率高 (3)cpu高速缓冲存取利用率高 实现如下: 测试如下: 队列的定义---Queue 队列只允许在队尾插入,队头删除.具有先进先出的特性. 队列的实现可用顺序表也可用链表. 若采用顺序表,删除时需要移动元素.为了操作方便,采取链表实现. 实现如下: 测试如下: 栈

非阻塞算法-栈

上一节我们以计数器作为例子描述了非阻塞算法,这一节我们拿一个稍微复杂一点的数据结构栈来讲述非阻塞算法的实践应用.1.单线程栈 public class SingleThreadStack implements Stack{ private Node head; public Node pop() { if (head == null) { return null; } Node h = head; head = head.getNext(); h.setNext(null); return h;

C语言栈队列实现二-十/二-八进制转换

C语言栈队列实现二-十/二-八进制转换 2015-04-05 Lover雪儿 1 //利用栈来求取二进制数的十进制与八进制的结果 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <math.h> 5 6 #define STACK_INIT_SIZE 20 //初始栈大小 7 #define STACK_INCREMENT 10 //扩充栈时每次增加的内存 8 9 typedef char ElemType;

java面向对象的栈 队列 优先级队列的比较

栈 队列 有序队列数据结构的生命周期比那些数据库类型的结构(比如链表,树)要短得多.在程序操作执行期间他们才被创建,通常用他们去执行某项特殊的任务:当完成任务之后,他们就会被销毁.这三个数据结构还有一个特点就是访问是受到限制的,即在特定时刻只有一个数据项可以被读取或者被删除,但是所谓的移除并不是真的删除,数据项依然在这些数据结构中,只不过因为指针已经指向其他数据项,没有办法访问到,当添加新的数据项时,当初移除的数据项被替代从而永远消失. 栈 队列 优先级队列的模拟思想 1.栈:栈遵循先进后出(F

java 集合 Connection 栈 队列 及一些常用

800x600 Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE MicrosoftInternetExplorer4 /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priori

算法 - 栈与队列(C 语言实现)

目标: 理解 栈 与 队列 这两种数据结构, 并且知道如何应用. 算法 + 数据结构 = 程序 一.堆栈 堆栈是一组元素的集合,类似于数组,但数组可以按下标访问,堆栈的访问规则只能为push 与 pop 两种操作. 堆栈只能访问或者移出栈顶的元素.

算法导论第十章 栈队列和链表

本章讲述的是基本的数据结构,如栈.队列和链表.这些都是最最基本的数据结构,具体的就不再啰嗦.然后本章也没有什么需要特别注意的点,哦,有一个小节:指针和对象的实现,可以认真看一下,大概就是用其他的实现方式来代替指针和对象的实现,因为有些语言不支持指针和对象数据类型,那在实现这种链式的数据结构就无法表示,本节介绍的方法就是利用数组和数组下标来构造对象和指针,说白了,就是利用数组来表示链式对象.个人感觉意义不大,权当了解得了. 结合一些常见的笔试面试题,我就用3个习题来总结这一章吧. 1.习题10.1