题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push、pop的时间复杂度都为O(l)。
算法分析:
要保证当栈中最小元素被弹出栈后,能在栈中找到一个次小的元素弹出。因此,我们可以把每次最小元素都保存起来放到另外一个辅助栈里。
首先往空的数据栈里压入数字3,显然现在数字3是最小值,我们也把这个最小值压入辅助栈中。接下来想数据栈中压入数字4,由于4大于之前的最小值,因此我们仍然往辅助栈中压入数字3.第三步继续往数据栈中压入数字2,由于2小于之前的最小值3,因此我们把最小值更新为2,并把2压入辅助栈。同样当压入1时,也要更新最小值,并把新的最小值1压入辅助栈中。
表.栈内压入3,4,2,1之后接连两次弹出栈顶数字再压入0时,数据栈、辅助栈和最小值的状态
步骤 | 操作 | 数据栈 | 辅助栈 | 最小值 |
1 | 压入3 | 3 | 3, | 3 |
2 | 压入4 | 3,4 | 3,3 | 3 |
3 | 压入2 | 3,4,2 | 3,3,2 | 2 |
4 | 压入1 | 3,4,2,1 | 3,3,2,1 | 1 |
5 | 弹出 | 3,4,2 | 3,3,2 | 2 |
6 | 弹出 | 3,4 | 3,3 | 3 |
7 | 压入0 | 3,4,0 | 3,3,0 | 0 |
从表中我们可以看出,如果每次都把最小的元素压入辅助栈,那么就能保证辅助栈顶一直都是最小元素。当最小元素从数据栈内被弹出后,同时弹出辅助栈的栈顶元素,此时辅助栈的新栈顶元素就是下一个最小值。
源程序:
/**************************************************************
* Copyright (c) 2016,
* All rights reserved.
* 版 本 号:v1.0
* 题目描述:包含min函数的栈
* 题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push、pop的时间复杂度都为O(l)。
*
* 输入描述:无
* 程序输出:无
* 问题分析:
* 算法描述: 要保证当栈中最小元素被弹出栈后,能在栈中找到一个次小的元素弹出。因此,我们可以把每次最小元素都保存起来
* 放到另外一个辅助栈里。
* 首先往空的数据栈里压入数字3,显然现在数字3是最小值,我们也把这个最小值压入辅助栈中。
* 接下来想数据栈中压入数字4,由于4大于之前的最小值,因此我们仍然往辅助栈中压入数字3.
* 第三步继续往数据栈中压入数字2,由于2小于之前的最小值3,因此我们把最小值更新为2,
* 并把2压入辅助栈。同样当压入1时,也要更新最小值,并把新的最小值1压入辅助栈中。
*
* 完成日期:2016-09-11
***************************************************************/
package org.marsguo.offerproject21;
import java.util.Stack;
public class MinStack {
Stack<Integer> data = new Stack<Integer>();
Stack<Integer> min = new Stack<Integer>();
Integer temp = null;
public void push(int node){
if(temp != null){ //是否是第一次入栈,不是的话比较大小
if(node <= temp){ //判断新压入的元素是否比已有的小,是的话则将新元素赋给temp
temp = node;
min.push(node);
}
data.push(node);
}else{
temp = node;
data.push(node);
min.push(node);
}
}
public void pop(){
int num = data.pop();
int num2 = min.pop();
if(num != num2){ //当弹出的两个值不相等的时候,需要重新将辅助栈中的刚刚弹出的元素压入栈
min.push(num2);
}
}
public int top(){
int num = data.pop(); //取出栈顶元素,
data.push(num); //同时还要取出后放回。
return num;
}
public int min(){
int num = min.pop(); //取出辅助栈中的最小元素,
min.push(num); //取出后同时需要放回。
return num;
}
}