常数时间内检索到最小元素的栈

常数时间 O(1)  指的是无论数据量多大,操作的执行时间都保持恒定不变,不会随着输入规模增加而增加。换句话说,不管栈中有 10 个元素还是 10 万个元素,执行某个操作(如获取最小元素)所需的时间都是一样的

例:

示例:
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 操作总是在 非空栈 上调用。

题目说明:

一般栈的 pop() 操作会移除栈顶元素,因此直接获取最小元素通常需要遍历整个栈O(n) 时间复杂度)。但是,我们可以通过辅助栈来优化,使 getMin() 操作始终保持 O(1) 复杂度。

核心思路:

  • push(x)

    • x 压入主栈 stack

    • 如果 x 小于等于 minStack 栈顶元素(或者 minStack 为空),也把 x 压入 minStack,保证 minStack 栈顶始终是当前栈中的最小值。

  • pop()

    • stack 中弹出元素。

    • 如果弹出的元素 恰好是 minStack 栈顶元素(当前最小值),那 minStack 也要同步弹出,保证 minStack 仍然正确维护当前最小值。
      为什么? 因为 minStack 记录的是当前栈中最小的元素,而当 stack.pop() 移除的元素正好是最小值时,我们必须同步更新 minStack,否则 minStack 可能会存储错误的最小值。

  • getMin()

    • 直接返回 minStack 栈顶元素即可,时间复杂度 O(1)

代码实现:
 1      const stack = {
 2         mainStack:[],
 3         minStack: [],
 4         push(x){
 5             this.mainStack.push(x);
 6             const len = this.minStack.length;
 7             if(len === 0 || x < this.minStack[len - 1]){
 8                 this.minStack.push(x);
 9             }
10         },
11         pop(){
12             if (this.mainStack.length === 0) return;
13             const lastNum = this.mainStack.pop();
14             if(lastNum === this.minStack[this.minStack.length -1]){
15                 this.minStack.pop();
16             }
17         },
18         getMin(){
19             return this.minStack[this.minStack.length -1];
20         }
21      }
22     stack.push(5);
23     stack.push(3);
24     stack.push(7);
25     console.log(stack.getMin()); // 输出 3
26     stack.pop();
27     console.log(stack.getMin()); // 仍然是 3
28     stack.pop();
29     console.log(stack.getMin()); // 输出 5

 

posted @ 2025-03-25 19:00  我是格鲁特  阅读(35)  评论(0)    收藏  举报