题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min,push及pop的时间复杂度是O(1)。
思路:自定义栈内,另建一个栈,用于存储最小值的数组下标。即,入栈时,通过最小值索引栈,得到当前最小值下标,取数组对应值,如果比入栈的当前值大,则将当前值入栈下标,压入到索引栈中;出栈时,若当前出栈值的索引为索引栈的栈顶元素,则索引栈也进行栈顶元素出栈操作。
算法代码:
package disizhang;
import java.util.Stack;
/**
* 自定义栈
*/
public class StackWithMin<E>
{
private int size = 16;//默认规模
private int nextSize = 16;//超过范围,扩展操作
private Object[] valArr;//存储数据结构
private int index = -1;//栈顶下标
private Stack<Integer> minStack;//存储最小值下标的栈
/**
* 构造器
*/
public StackWithMin()
{
valArr = new Object[size];
minStack = new Stack<Integer>();
}
/**
* 入栈
* @param value
*/
public void push(E value)
{
//不能为空
if (null == value)
{
throw new NullPointerException("Pushed value can not be null!");
}
//入参必须为可比较的
if (!(value instanceof Comparable))
{
throw new UnsupportedOperationException("The value must be Comparable!");
}
//栈满了,重构栈
if (index >= size)
{
resetStack();
}
//入栈
valArr[++index] = value;
//最小值的索引入栈
checkMinObj(value);
}
/**
* 最小索引入栈思想
* @param value
*/
@SuppressWarnings("unchecked")
private void checkMinObj(E value)
{
//第一个参数,直接为最小参数
if (index == 0)
{
minStack.push(index);
return;
}
//入参的值
Comparable valueComp = (Comparable) value;
//当前最小值
Comparable valueMinComp = (Comparable) valArr[minStack.peek()];
//新入栈的值小于当前最小值,则当前索引入栈
if (valueComp.compareTo(valueMinComp) < 0)
{
minStack.push(index);
}
}
/**
* 出栈
*/
@SuppressWarnings("unchecked")
public E pop()
{
//栈为空,报错
if (index < 0)
{
throw new NullPointerException("The statck is empty!");
}
//若是最小值出栈(比较下标判断),需要将其索引出栈
if (index == minStack.peek())
{
minStack.pop();
}
//出栈
return (E) valArr[index--];
}
/**
* 最小值
*/
@SuppressWarnings("unchecked")
public E getMin()
{
//return (E) minArr[index];//笨办法
//若栈空,则报错空指针
if (index < 0)
{
throw new NullPointerException("The statck is empty,no minValue returned!");
}
return (E) valArr[minStack.peek()];
}
/**
* 重构栈
*/
private void resetStack()
{
size += nextSize;
Object[] newArr = new Object[size];
System.arraycopy(valArr, 0, newArr, 0, size - nextSize);
valArr = newArr;
}
//测试
public static void main(String[] args)
{
//栈初始化//也可以直接使用Integer等实现了Comparable接口的封装类
StackWithMin<MyValue> stack = new StackWithMin<MyValue>();
//初始化几个值
MyValue v1 = new MyValue(1);
MyValue v2 = new MyValue(2);
MyValue v3 = new MyValue(3);
MyValue v4 = new MyValue(4);
MyValue v5 = new MyValue(5);
//入栈
stack.push(v5);
stack.push(v4);
stack.push(v3);
stack.push(v2);
stack.push(v1);
stack.push(v4);
stack.push(v1);
//最小值
System.out.println("min: " + stack.getMin());
//出栈
System.out.println("pop: " + stack.pop());
System.out.println("min: " + stack.getMin());
System.out.println("pop: " + stack.pop());
System.out.println("min: " + stack.getMin());
System.out.println("pop: " + stack.pop());
System.out.println("min: " + stack.getMin());
System.out.println("pop: " + stack.pop());
System.out.println("min: " + stack.getMin());
System.out.println("pop: " + stack.pop());
//最小值
System.out.println("min: " + stack.getMin());
System.out.println("min: " + stack.getMin());
System.out.println("pop: " + stack.pop());
System.out.println("min: " + stack.getMin());
System.out.println("pop: " + stack.pop());
}
}
/**
* 自定义数值类
*/
class MyValue
implements Comparable<MyValue>
{
private int value;
public MyValue(int value)
{
this.value = value;
}
public int getValue()
{
return value;
}
public int compareTo(MyValue obj)
{
//不能与null比较
if (null == obj)
{
throw new NullPointerException("Can not compare to null!");
}
return this.value - obj.getValue();
}
@Override
public String toString()
{
return "" + value;
}
}
本篇博文参考:http://blog.csdn.net/oh_maxy/article/details/11533345