实现一个栈,该栈带有出栈(pop)、入栈(push)、取最小元素(getMin)3个方法。要保证这3个方法的时间复杂度都是O(1)

问题

实现一个栈,该栈带有出栈(pop)、入栈(push)、取最小元素(getMin)3个方法。要保证这3个方法的时间复杂度都是O(1)。

解释

为了实现一个栈,同时满足 poppush 和 getMin 操作的时间复杂度均为 O(1),我们需要在栈中存储元素的同时,额外维护一个最小值的信息。一个常见的方法是使用两个栈,一个用于存储实际元素(我们称之为 dataStack),另一个用于存储对应位置的最小值(我们称之为 minStack)。当 dataStack 进行 push 或 pop 操作时,minStack 也会进行相应的操作以保持同步,从而确保 getMin 操作的时间复杂度为 O(1)。

代码

import java.util.Stack;  
  
public class MinStack {  
    // 用于存储实际数据的栈  
    private Stack<Integer> dataStack;  
    // 用于存储对应位置最小值的栈  
    private Stack<Integer> minStack;  
  
    /** initialize your data structure here. */  
    public MinStack() {  
        dataStack = new Stack<>();  
        minStack = new Stack<>();  
    }  
  
    public void push(int x) {  
        dataStack.push(x);  
        // 如果minStack为空,或者x小于等于minStack的栈顶元素,则将x也压入minStack  
        if (minStack.isEmpty() || x <= minStack.peek()) {  
            minStack.push(x);  
        }  
    }  
  
    public void pop() {  
        // 如果dataStack弹出的元素等于minStack的栈顶元素,则minStack也需要弹出  
        if (!dataStack.isEmpty() && dataStack.peek().equals(minStack.peek())) {  
            minStack.pop();  
        }  
        dataStack.pop();  
    }  
  
    public int top() {  
        // 栈不为空时,返回栈顶元素  
        if (!dataStack.isEmpty()) {  
            return dataStack.peek();  
        }  
        throw new RuntimeException("Stack is empty");  
    }  
  
    public int getMin() {  
        // 栈不为空时,返回最小值栈的栈顶元素  
        if (!minStack.isEmpty()) {  
            return minStack.peek();  
        }  
        throw new RuntimeException("Stack is empty");  
    }  
}  
  
// 示例用法  
public class Main {  
    public static void main(String[] args) {  
        MinStack minStack = new MinStack();  
        minStack.push(-2);  
        minStack.push(0);  
        minStack.push(-3);  
        System.out.println(minStack.getMin());   // 返回 -3  
        minStack.pop();  
        System.out.println(minStack.top());     // 返回 0  
        System.out.println(minStack.getMin());   // 返回 -2  
    }  
}

这段代码定义了一个 MinStack 类,它使用两个栈来分别维护数据和对应位置的最小值。push 操作会同时向两个栈中添加元素,而 pop 操作会检查两个栈的栈顶元素是否相同(即被移除的元素是否是当前最小值),如果是,则同时从两个栈中移除。通过这种方式,我们可以确保 getMin 操作的时间复杂度为 O(1)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,这是一个基本的顺序实现,包含入栈(push)和出栈(pop)操作。 ``` #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 // 定义的最大容量 typedef struct { int data[MAXSIZE]; // 存放元素 int top; // 顶指针 } SqStack; // 初始化 void InitStack(SqStack *S) { S->top = -1; // 顶指针初始化为-1 } // 判断是否为空 int StackEmpty(SqStack S) { if (S.top == -1) { // 顶指针为-1,为空 return 1; } return 0; } // 判断是否已满 int StackFull(SqStack S) { if (S.top == MAXSIZE - 1) { // 顶指针等于最大容量减一,已满 return 1; } return 0; } // 入栈操作 int Push(SqStack *S, int x) { if (StackFull(*S)) { // 已满,无法入栈 return 0; } S->top++; // 顶指针加一 S->data[S->top] = x; // 将元素x入栈 return 1; } // 出栈操作 int Pop(SqStack *S, int *x) { if (StackEmpty(*S)) { // 为空,无法出栈 return 0; } *x = S->data[S->top]; // 将元素出栈 S->top--; // 顶指针减一 return 1; } int main() { SqStack S; int x; InitStack(&S); // 初始化 Push(&S, 1); // 入栈 Push(&S, 2); Push(&S, 3); Pop(&S, &x); // 出栈 printf("%d\n", x); // 输出出栈元素 Pop(&S, &x); printf("%d\n", x); Pop(&S, &x); printf("%d\n", x); Pop(&S, &x); // 尝试出栈 return 0; } ``` 需要注意的是,顶指针的初始值应该为-1,而不是0。在入栈操作时,先将顶指针加一,再将元素入栈;在出栈操作时,先将元素出栈,再将顶指针减一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没出过地球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值