Leetcode 刷题日记
2021.2.6
题目链接:
https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof/submissions/
问题描述:
实现一个栈,通过调用min()方法,查询栈中的最小元素,该方法的时间复杂度必须为O(1)
解答1:
栈(Stack)+有序表(SortedList)
代码:
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Stack;
class MinStack {
ArrayList<Integer> sortedList = new ArrayList<>();
Stack<Integer> stack = new Stack();
public MinStack() {
}
public void push(int x) {
stack.push(x);
sortedList.add(x);
}
public void pop() {
sortedList.remove(stack.pop());
}
public int top() {
return stack.peek();
}
public int min() {
sortedList.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
if(o1 < 0 && o2 >= 0) return -1;
else if(o1 > 0 && o2 <= 0) return 1;
else return o1 - o2;
}
});
return sortedList.get(0);
}
public static void main(String[] args) {
MinStack stack = new MinStack();
stack.push(2147483647);
stack.push(-2147483648);
System.out.println(stack.min());
}
}
分析:
时间复杂度:O(nlog(n))
空间复杂度:O(n)
运行结果:
评注:
这是笔者首先想到的方法:通过额外维护一个有序表来实现min函数的常数性能。但是,这个题并没有较好地完成任务。由于使用了归并排序,min()方法的时间复杂度远远高于O(1) ( 实际为O(nlog(n)) ) ,空间复杂度也不容乐观。此题的时间要求宽松,所以侥幸能过。
题外话:笔者在第一次用这个思路写代码时犯了一个小错误。在利用ArrayList的sort()方法时,必须传入一个Comparator的匿名类。我在实现Comparator的compare()方法时,直接返回o1-o2,这可能会导致整型溢出,需要进行简单的优化。
解答2:
(摘自https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof/solution/mian-shi-ti-30-bao-han-minhan-shu-de-zhan-fu-zhu-z/)
栈+栈
代码:
import java.util.Stack;
class MinStack {
Stack<Integer> stack1 = new Stack();
Stack<Integer> stack2 = new Stack<>();
public MinStack() {
}
public void push(int x) {
stack1.push(x);
if(stack2.isEmpty() || x <= stack2.peek()) stack2.push(x);
}
public void pop() {
if(stack2.peek().equals(stack1.pop())) stack2.pop();
}
public int top() {
return stack1.peek();
}
public int min() {
return stack2.peek();
}
}
分析:
时间复杂度:O(1)
空间复杂度:O(1)
运行结果:
评注:
这个方法是笔者比较欣赏的一个方法,其运行时间由三位数降至两位数,较好地实现了题目的要求。这个思路有助于深入理解栈作为一个“储存工具”的作用,启发我们栈可以用来实现“有序储存”,即栈内元素按升序或降序储存。