美文网首页
白话文讲栈

白话文讲栈

作者: 幺鹿 | 来源:发表于2019-04-10 19:15 被阅读0次

思考题

给定一个仅包含字符:(,),[,]的字符串,确定输入字符串是否有效。
字符串有效的定义如下:

  • 开括号必须用同一类型的括号闭合。
  • 开方括号必须按正确顺序闭合。
// 示例1
Input: "()"
Output: true
// 示例2
Input: "()[]{}"
Output: true
// 示例3
Input: "(]"
Output: false

可以先思考一下这个问题,是否可以结合栈解决呢?

栈(stack)又名堆栈,它是一种操作受限的线性表。其限制是仅允许在线性表头进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。

  • 向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;
  • 从一个栈删除元素又称作出栈、退栈或弹栈,它是把栈顶元素删掉,使下方的元素成为新的栈顶元素;

栈按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。

关于栈我列举一个很贴切的例子,就是一摞叠在一起的书。假设我们平时放书的时候,都是从下往上一本一本的放,取书的时候也都是从上往下一本一本的取,不能从中间任意位置抽取和放置,这就是典型的栈结构。


一叠书.png

如何实现栈呢?

前面我们讲解过数组和链表,栈也可以使用这两个数据结构去实现。基于数组实现的栈,我们称之为数组栈。基于链表实现的栈,我们称之为链式栈。由于数组的特性,数组栈的空间是有界的,当栈的空间不满足需求时,需要执行扩容。而链表理论上则是无界的,因为实际受到物理资源限制。

// 基于数组实现的顺序栈
public class ArrayStack {
  private String[] items;  // 数组
  private int count;       // 栈中元素个数
  private int n;           // 栈的大小

  // 初始化数组,申请一个大小为 n 的数组空间
  public ArrayStack(int n) {
    this.items = new String[n];
    this.n = n;
    this.count = 0;
  }

  // 入栈操作
  public boolean push(String item) {
    // 数组空间不够了,直接返回 false,入栈失败。
    if (count == n) return false;
    // 将 item 放到下标为 count 的位置,并且 count 加一
    items[count] = item;
    ++count;
    return true;
  }
  
  // 出栈操作
  public String pop() {
    // 栈为空,则直接返回 null
    if (count == 0) return null;
    // 返回下标为 count-1 的数组元素,并且栈中元素个数 count 减一
    String tmp = items[count-1];
    --count;
    return tmp;
  }
}

了解了定义和基本操作,那它的操作的时间、空间复杂度是多少呢?

不管是顺序栈还是链式栈,我们存储数据只需要一个大小为 n 的数组就够了。在入栈和出栈过程中,只需要一两个临时变量存储空间,所以空间复杂度是 O(1)。

注意,这里存储数据需要一个大小为 n 的数组,并不是说空间复杂度就是 O(n)。因为,这 n 个空间是必须的,无法省掉。所以我们说空间复杂度的时候,是指除了原本的数据存储空间外,算法运行还需要额外的存储空间。

空间复杂度分析是不是很简单?时间复杂度也不难。不管是顺序栈还是链式栈,入栈、出栈只涉及栈顶个别数据的操作,所以时间复杂度都是 O(1)。

Java中的栈的实现

Java中的栈我们主要关注Stack类,它继承自VectorVector是线程安全容器,但由于使用synchronized锁,在要求高性能高并发环境下并不推荐。

Stack使用数组存储元素,但凡使用数组构建的数据结构都会有一个共通的问题——需要扩容。在JDK8中,默认情况下Stack的扩容规则是当栈的大小等于容量大小时,则将当前容量扩大为现在容量的两倍。如果要修改默认扩容行为,可以通过构造器设定扩容的步长,以求更合理的配置扩容。

Object (java.lang)
       AbstractCollection (java.util)
              AbstractList (java.util)
                     Vector (java.util)
                            Stack (java.util)

解答思考题

使用栈这种数据结构,使得我们很容易解决诸如逆波兰式汉诺塔等问题。熟悉栈的定义并不难,但我们对栈的理解不能仅仅停留在静态栈的层面上,更多的需要思考栈的动态性,结合这些动态性我们可以解决哪些问题。

class Solution {
    public boolean isValid(String s) {

        if ((s.length() & 1) == 1) {
            return false;
        }

        HashMap<Character, Character> symbolMap = new HashMap<>();
        symbolMap.put(')', '(');
        symbolMap.put('}', '{');
        symbolMap.put(']', '[');

        Stack<Character> stack = new Stack<>();

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            switch (c) {
                case ')':
                case '}':
                case ']':
                    if (stack.empty()) {
                        return false;
                    } else if (Objects.equals(stack.lastElement(), symbolMap.get(c))) {
                        stack.pop();
                    } else {
                        stack.push(c);
                    }
                    break;
                default:
                    stack.push(c);
                    break;
            }
        }
        return stack.empty();
    }
}

相关文章

  • 白话文讲栈

    思考题 给定一个仅包含字符:(,),[,]的字符串,确定输入字符串是否有效。字符串有效的定义如下: 开括号必须用同...

  • 白话文讲数组

    数组三大特性 数组是一种线性表的数据结构,它使用一组连续的内存空间,来存储一组具有相同类型的数据。 有三个关键词可...

  • 轮廓检测

    白话文讲计算机视觉-第六讲-轮廓检测算法 OpenCV中findcounter所用轮廓提取算法理解 [Suzuki...

  • js堆,栈与队列的区别

    栈的定义 栈的常用操作 栈中有两个基本的操作 推入 :从栈的顶端推入一个数据,依次往下推 弹出 :讲栈顶端的数据移...

  • 数据结构与算法第四讲 - 栈

    本讲内容 栈的定义栈的操作栈的实现栈的应用 问题引入:思考一下浏览器的前进和后退功能有什么特征?是怎么实现的? 页...

  • 字节跳动后端面经四

    jvm为什么分为堆和栈?堆和栈是什么,具体讲一讲 TCP相较于UDP是如何保证安全性 http版本的区别 http...

  • 栈的顺序存储结构

    栈的顺序存储结构 栈是一种重要的线性结构,可以这样讲,栈是线性表的一种具体形式。 栈这种后进先出的数据结构应用是非...

  • Python学习教程:用队列实现栈

    接着上一期跟大家说的用栈实现队列,这期的Python学习教程跟大家讲用队列实现栈 题目:使用队列实现栈的下列操作:...

  • iOS逆向:函数本质(上)

    本文的主要目的是理解函数栈以及涉及的相关指令 在讲函数的本质之前,首先需要讲下以下几个概念栈、SP、FP 常识 栈...

  • [032]Binder远程转本地

    前言 在[031]Binder线程栈复用中,我们说到Binder驱动通过“线程栈复用”减少线程数,我们来讲一讲另外...

网友评论

      本文标题:白话文讲栈

      本文链接:https://www.haomeiwen.com/subject/qssbiqtx.html