害,昨天犯懒,一晚上没学习,就没做(爬
今天补上
题目描述
设计一个最小栈,可以完成栈最基本的push、pop、top功能,除此之外要实现一个getMin方法,在常数时间内得到当前栈中的最小值
解题思路
(1)一个不符合题目要求的做法:使用List结构来模拟栈的操作,push即加入list,pop和top则是操作list的最后一个元素,getMin则需要对list进行一个遍历操作找到最小值。由于需要遍历,getMin的时间复杂度为O(N),不符合题目要求。
(2) 想办法存下最小值。因为题目要求在常数时间内返回最小值,那么就意味着我们必须采用某种方法提前存下最小值,而不是等到要获得最小值时才去所有的数里面找。对于正常存入最小栈中的数据,我们可以就直接采用一个栈来保存,而对于保存最小值,有以下几种方法:
图片解说来自题解:https://leetcode-cn.com/problems/min-stack/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-38/
法一: 使用一个额外的栈保存最小值。
在最开始的时候我考虑过用一个额外的变量来保存最小值,而变量的问题在于:当前最小值被pop出去之后,第二小的元素(即pop之后的最小值)应该怎么获取?也就是说,在这道题目中,保存最小值并非只保存一个当前数据就可以,而是要保存一个 “最小值序列”。
因此就会想到,是不是可以用一个额外的数据结构来保存这个最小值序列呢?
法一就是使用了一个额外的栈,具体做法是:当第一个元素入栈时,将其加入最小栈;后续元素入(基本)栈时,将其与最小栈的栈顶比较,如果比栈顶元素大,就不管,反之就将这个元素加入最小栈

代码如下:
class MinStack {
/** initialize your data structure here. */
Stack<Integer> stack;
Stack<Integer> minStack;
public MinStack() {
this.stack = new Stack<>();
this.minStack = new Stack<>();
}
public void push(int x) {
stack.push(x);
if (minStack.size() == 0 || x <= minStack.peek()) {
minStack.push(x);
}
}
public void pop() {
int tmp = stack.peek();
stack.pop();
if (minStack.peek() == tmp) {
minStack.pop();
}
}
public int top() {
return stack.peek();
}
public int getMin() {
return minStack.peek();
}
}
法二: 只使用一个栈,同时保存数据序列和最小值。
主要问题就是,当最小值有更新的时候,如何把前一个最小值保存下来。只使用一个栈时可以进行如下操作:
(1)当最小值更新时,先将前一个最小值压栈,然后更新最小值且将当前最小值压栈
(2)当出栈的数值和当前最小值相等时,再进行一次出栈操作,也就是恢复前一个最小值

(按照这个思路写的代码也比较简单,就不再重复了)
(3) (2)中的方法都是基于直接使用Java的栈来保存数据序列,当然我们也可以不用自带的栈,可以考虑用一个链表,在每一个Node节点中都增加一个min字段,每次push的时候就确定该node的min值,直接从底层数据结构就解决了最小值的问题。
这里需要注意,由于我们每次都是操作栈顶元素,因此每次push的时候都可以将节点加入首部
以下代码来自题解,也比较简单:
class MinStack {
class Node{
int value;
int min;
Node next;
Node(int x, int min){
this.value=x;
this.min=min;
next = null;
}
}
Node head;
//每次加入的节点放到头部
public void push(int x) {
if(null==head){
head = new Node(x,x);
}else{
//当前值和之前头结点的最小值较小的做为当前的 min
Node n = new Node(x, Math.min(x,head.min));
n.next=head;
head=n;
}
}
public void pop() {
if(head!=null)
head =head.next;
}
public int top() {
if(head!=null)
return head.value;
return -1;
}
public int getMin() {
if(null!=head)
return head.min;
return -1;
}
}
本文详细探讨了设计一个具备快速获取最小值功能的栈的方法。通过对比不同策略,包括使用额外栈保存最小值序列和在单个栈中同时保存数据与最小值,展示了如何在常数时间内获取栈中的最小值,提供了具体的代码实现。
1890

被折叠的 条评论
为什么被折叠?



