返回

剑指Offer 30:含min函数的栈

前端

引言

栈是一种重要的数据结构,它遵循后进先出的原则,即最后进栈的元素最先出栈。在许多计算机科学问题和算法中,栈都被广泛应用。

剑指Offer第30题「包含min函数的栈」是一个经典的栈问题,它要求我们设计一个栈,除了具有基本的栈操作(如压栈、出栈和取栈顶元素)外,还能够在O(1)的时间复杂度内返回栈中的最小元素。

问题分析

为了解决这个问题,我们需要仔细分析问题的要求。首先,我们需要维护一个栈,以便能够执行基本的栈操作。其次,我们需要一种方法来跟踪栈中的最小元素,以便能够在O(1)的时间复杂度内返回它。

解决方案

有两种主要的方法可以解决这个问题:

  1. 使用辅助栈 :我们可以使用一个辅助栈来存储栈中的最小元素。当我们将一个元素压入栈时,我们将其与辅助栈中的最小元素进行比较,并将较小的元素压入辅助栈。当我们从栈中弹出元素时,我们也从辅助栈中弹出相应的最小元素。这样,辅助栈始终包含栈中的最小元素,并且我们可以通过访问辅助栈的栈顶元素来获取它。

  2. 使用一个变量存储最小值 :另一种方法是使用一个变量来存储栈中的最小值。当我们将一个元素压入栈时,我们将其与当前的最小值进行比较,并将较小的元素存储在变量中。当我们从栈中弹出元素时,我们检查变量中的值是否等于弹出元素,如果是,则更新变量中的值。这样,变量中的值始终包含栈中的最小元素,并且我们可以通过访问变量来获取它。

代码实现

以下是用Java实现的两种解决方案:

import java.util.Stack;

public class MinStack {

    private Stack<Integer> stack;
    private Stack<Integer> minStack;

    public MinStack() {
        stack = new Stack<>();
        minStack = new Stack<>();
    }

    public void push(int x) {
        stack.push(x);
        if (minStack.isEmpty() || x <= minStack.peek()) {
            minStack.push(x);
        }
    }

    public int pop() {
        int x = stack.pop();
        if (x == minStack.peek()) {
            minStack.pop();
        }
        return x;
    }

    public int getMin() {
        return minStack.peek();
    }
}
import java.util.Stack;

public class MinStack {

    private Stack<Integer> stack;
    private int min;

    public MinStack() {
        stack = new Stack<>();
        min = Integer.MAX_VALUE;
    }

    public void push(int x) {
        stack.push(x);
        if (x < min) {
            min = x;
        }
    }

    public int pop() {
        int x = stack.pop();
        if (x == min) {
            min = Integer.MAX_VALUE;
            for (int i : stack) {
                if (i < min) {
                    min = i;
                }
            }
        }
        return x;
    }

    public int getMin() {
        return min;
    }
}

复杂度分析

对于第一种解决方案,每次压栈和出栈的时间复杂度都是O(1),返回最小值的时间复杂度也是O(1)。

对于第二种解决方案,压栈和出栈的时间复杂度都是O(1),返回最小值的时间复杂度最坏情况下是O(n),但在大多数情况下是O(1)。

总结

在本文中,我们介绍了剑指Offer第30题「包含min函数的栈」的两种解决方案。第一种解决方案使用辅助栈来存储栈中的最小元素,而第二种解决方案使用一个变量来存储栈中的最小值。这两种解决方案都有各自的优缺点,开发者可以根据自己的需要选择适合自己的解决方案。