数据结构之栈

171 阅读2分钟

一、定义

栈(Stack)是一种常见的数据结构,它遵循后进先出(LIFO,Last-In-First-Out)的原则。类比于现实生活中的栈,比如一摞书,你只能从最顶端取出或放入书籍,而不能从中间或底部进行操作。

二、封装栈结构

栈具有以下两个主要操作:

  1. 入栈(Push):将元素压入栈顶。
  2. 出栈(Pop):从栈顶移除一个元素,并返回该元素。

栈还可能包含其他辅助操作,如:

  1. 栈顶元素访问(Peek):获取栈顶的元素值,但不对栈进行修改。
  2. 栈的大小(Size):返回栈中元素的数量。
  3. 栈是否为空(isEmpty):检查栈是否为空,如果为空则返回 true,否则返回 false。
class Stack {
  constructor() {
    this.items = [];
  }

  push(element) {
    this.items.push(element);
  }

  pop() {
    if (this.isEmpty()) {
      return null;
    }
    return this.items.pop();
  }

  peek() {
    if (this.isEmpty()) {
      return null;
    }
    return this.items[this.items.length - 1];
  }

  size() {
    return this.items.length;
  }

  isEmpty() {
    return this.items.length === 0;
  }
}

三、拓展

1. 单调栈

1. 定义

  • 单调栈(Monotonic Stack)是一种常见的算法技巧,主要用于解决一些与单调性相关的问题。单调栈的基本思想是维护一个栈,栈内的元素满足一定的单调性。对于单调递增栈来说,栈内元素从栈底到栈顶是递增的;对于单调递减栈来说,栈内元素从栈底到栈顶是递减的。
  • 它通常用于寻找数组中元素的下一个更大或更小的元素。
  • 时间复杂度是O(n)

2. 代码模板

function monotoneStack(数据参数){
   //定义一个结果容器
   const stack = []
   //从右边开始查找是逆序
   for(遍历数据){
       //保证栈顶是最大的或最小的
       while(stack.length && 满足一个判断条件){
           出栈操作
       }
       其他的一些计算
       入栈操作
   }
   返回结果
}

3. 应用

  1. [496] 下一个更大元素
  • 题目描述:
    • 给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每个元素在 nums2 中的下一个比其大的值。
    • nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出-1。
  • 代码实现
/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var nextGreaterElement = function (nums1, nums2) {
    //O(m+n)
    let m = nums1.length;
    let n = nums2.length;
    const stack = [];//单调栈
    const resMap = new Map();
    //找出nums2每个元素,右边更大的元素
    for (let i = n - 1; i >= 0; i--) {
        //保证栈顶是最大的
        while (stack.length > 0 && stack[stack.length - 1] <= nums2[i]) {
            stack.pop();
        }
        resMap.set(nums2[i], stack.length > 0 ? stack[stack.length - 1] : -1);
        stack.push(nums2[i]);
    }
    const res = [];
    for (let i = 0; i < m; i++) {
        res.push(resMap.get(nums1[i]));
    }

    return res;
}