跳至主要內容

包含min函数的栈

soulballad算法剑指Offer剑指Offer约 494 字大约 2 分钟

题目:

​ 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度都是 O(1)。

分析:

​ 看到这个问题,第一反应是每次压入一个元素进栈都将栈里的元素排序,让最小的元素位于栈顶,这样 min 函数的事件复杂度就是 O(1) 了。但这种方法没法保证最后压入的元素最先出栈,因此这种数据结构已经不是栈了。

​ 接着想到使用一个成员变量存放最小的元素。每次压入一个新元素时,如果该元素比当前最小元素还要小,则更新最小的元素。最小元素弹出之后要能得到次小元素,因此也要把第二次小的元素保存起来。

​ 下面表格使用一个数据栈和一个辅助栈来保存元素,每次压入元素时要保存到数据栈,辅助栈里面保存有序的元素,min 使用辅助栈来获取元素,保证 O(1) 时间复杂度。

步骤操作数据栈辅助栈最小值
1压入3333
2压入43, 43, 33
3压入23, 4, 23, 3, 22
4压入13, 4, 2, 13, 3, 2, 11
5弹出3, 4, 23, 3, 22
6弹出3, 43, 33
7压入03, 4, 03, 3, 00

代码:

public class StackWithMin {

    private static Stack<Integer> data_stack = new Stack();
    private static Stack<Integer> min_stack = new Stack();

    public static void push(Integer num) {
        data_stack.push(num);

        if (min_stack.size() == 0 || num < min_stack.peek()) {
            min_stack.push(num);
        }else{
            min_stack.push(min_stack.peek());
        }
    }

    public static void pop() {
        data_stack.pop();
        min_stack.pop();
    }

    public static Integer min() {
        return min_stack.peek();
    }
}

测试:

@Test
public void test() {
    StackWithMin.push(3);
    StackWithMin.push(4);
    StackWithMin.push(2);
    System.out.println(StackWithMin.min());
    StackWithMin.pop();
    System.out.println(StackWithMin.min());
    StackWithMin.push(5);
    System.out.println(StackWithMin.min());
    StackWithMin.pop();
    System.out.println(StackWithMin.min());
    StackWithMin.push(1);
    StackWithMin.push(0);
    System.out.println(StackWithMin.min());
}
上次编辑于:
贡献者: soulballad