【算法刷题】C01-Q01 设计一个有getMin功能的栈

C01-Q01 设计一个有getMin功能的栈

参考:《程序员代码面试指南》第1章第1题

LeetCode:https://leetcode-cn.com/problems/min-stack/

题目要求

实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。

  1. pop、push、getMin 操作的时间复杂度都是 O(1)。
  2. 设计的栈类型可以使用现成的栈结构。

个人解法

【思路】

用2个栈,一个普通的先进后出的栈stack,另一个栈minStack用于存迄今为止的最小值,当pop或者push的时候,将元素与minStack栈顶元素进行比较,小于等于就放进minStack。

【Tips】

获取minStack栈顶元素时,需要先判断栈是否为空,否则会抛异常

【结果】

执行用时:8 ms, 在所有 Java 提交中击败了29.51% 的用户

内存消耗:40.1 MB, 在所有 Java 提交中击败了68.38% 的用户

【Code】

class MinStack1 {
    private Stack<Integer> stack;
    private Stack<Integer> min;

    public MinStack1() {
        stack = new Stack<>();
        min = new Stack<>();
    }

    public int pop() {
        Integer e = stack.pop();
        if (e.equals(min.peek())) {
            min.pop();
        }
        return e;
    }

    public int top() {
        return stack.peek();
    }

    public void push(int e) {
        stack.push(e);
        if (min.isEmpty()) {
            min.push(e);
            return;
        }
        if (e <= min.peek()) {
            min.push(e);
        }
    }

    public int getMin() {
        return min.peek();
    }
}

优秀解法

【思路】

用1个栈实现,每次插入一个数字对{n,min}。例如:插入2时就是{2,2},插入1时就是{1,1},插入3时就是{3,1}

【结果】

执行用时:6 ms, 在所有 Java 提交中击败了95.98% 的用户

内存消耗:39.8 MB, 在所有 Java 提交中击败了97.24% 的用户

【Code】

class MinStack2 {
    private Stack<int[]> stack;

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

    public int pop() {
        return stack.pop()[0];
    }

    public int top() {
        return stack.peek()[0];
    }

    public void push(int e) {
        if (stack.isEmpty()) {
            stack.push(new int[]{e, e});
            return;
        }
        int min = Math.min(e, stack.peek()[1]);
        stack.push(new int[]{e, min});
    }

    public int getMin() {
        return stack.peek()[1];
    }
}

测试代码

@Test
public void testMinStack1() {
    MinStack1 stack = new MinStack1();
    stack.push(2);
    assert stack.getMin() == 2;
    stack.push(3);
    assert stack.getMin() == 2;
    stack.push(1);
    assert stack.getMin() == 1;
    stack.push(4);
    assert stack.getMin() == 1;

    assert stack.pop() == 4;
    assert stack.getMin() == 1;
    assert stack.pop() == 1;
    assert stack.getMin() == 2;
}

@Test
public void testMinStack2() {
    MinStack2 stack = new MinStack2();
    stack.push(2);
    assert stack.getMin() == 2;
    stack.push(3);
    assert stack.getMin() == 2;
    stack.push(1);
    assert stack.getMin() == 1;
    stack.push(4);
    assert stack.getMin() == 1;

    assert stack.pop() == 4;
    assert stack.getMin() == 1;
    assert stack.pop() == 1;
    assert stack.getMin() == 2;
}
posted @ 2020-12-28 16:49  爱Code的王饱饱  阅读(82)  评论(0编辑  收藏  举报