返回

栈中最小元素的快速获取:从伪代码到JS实现

前端

在计算机科学中,栈是一种先进后出(LIFO)的数据结构。为了在栈中快速获取最小元素,我们可以使用一个辅助栈来记录当前最小值。当我们向主栈中压入元素时,如果新元素比辅助栈顶的元素小,则将新元素压入辅助栈。否则,将辅助栈顶元素压入辅助栈,再将新元素压入主栈。当我们从主栈中弹出元素时,如果弹出元素与辅助栈顶元素相等,则辅助栈也弹出元素。

下面是该算法的伪代码:

// 主栈
main_stack = []

// 辅助栈(用于存储最小值)
min_stack = []

// 入栈操作
push(element):
    // 将元素压入主栈
    main_stack.append(element)

    // 如果辅助栈为空,或者新元素小于辅助栈顶元素
    if min_stack.isEmpty() or element < min_stack[-1]:
        // 将新元素压入辅助栈
        min_stack.append(element)
    // 出栈操作
pop():
    // 如果主栈为空
    if main_stack.isEmpty():
        // 返回一个错误
        raise IndexError("Stack is empty")

    // 获取并移除主栈顶元素
    element = main_stack.pop()

    // 如果弹出元素与辅助栈顶元素相等
    if element == min_stack[-1]:
        // 移除辅助栈顶元素
        min_stack.pop()

    // 返回弹出元素
    return element

// 获取最小元素操作
min():
    // 如果辅助栈为空
    if min_stack.isEmpty():
        // 返回一个错误
        raise IndexError("Stack is empty")

    // 返回辅助栈顶元素
    return min_stack[-1]

现在,让我们使用JavaScript实现这个算法:

class Stack {
  constructor() {
    this.mainStack = [];
    this.minStack = [];
  }

  push(element) {
    this.mainStack.push(element);
    if (this.minStack.length === 0 || element <= this.minStack[this.minStack.length - 1]) {
      this.minStack.push(element);
    }
  }

  pop() {
    if (this.mainStack.length === 0) {
      throw new Error("Stack is empty");
    }
    const element = this.mainStack.pop();
    if (element === this.minStack[this.minStack.length - 1]) {
      this.minStack.pop();
    }
    return element;
  }

  min() {
    if (this.minStack.length === 0) {
      throw new Error("Stack is empty");
    }
    return this.minStack[this.minStack.length - 1];
  }
}

这个JavaScript实现与伪代码非常相似。它使用两个数组来实现主栈和辅助栈。push()方法将元素压入主栈,并在辅助栈中记录当前最小值。pop()方法从主栈中弹出元素,并在辅助栈中弹出与弹出元素相等的元素。min()方法返回辅助栈顶部的元素,即当前的最小值。

使用栈来存储最小值是一种非常有效的方法,因为它可以在常数时间内完成。这使得它非常适合于需要快速访问最小值的应用程序,例如堆栈跟踪、内存管理和编译器。