[算法最优]设计一个有getMin功能的栈

来源:互联网 发布:电信机顶盒网络连接 编辑:程序博客网 时间:2024/06/02 05:27

题目:

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

要求:

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


首先看下我写的,思路大概就是用两个栈,一个栈用于自定义栈的弹出,压入,辅助栈用于存放最小值,当压入第一个栈的时候,会判断辅助栈是否为空,如果为空也压入,如果不为空,就比较,如果小于等于辅助栈的第一个值,就压入。弹出操作,如果第一个栈弹出的数和辅助栈的第一个数相等,也弹出辅助栈的第一个数,getMin()获取辅助栈的顶部的数据就好。

代码如下:

package 设计一个有getMin功能的栈;import java.util.Stack;/** * 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作 * ==================== * 要求: * 1.pop、push、getMin操作的时间复杂都是O(1) * 2.设计的栈类型可以使用现成的栈结构 *  * @author dream * */public class MyStack1 {    private Stack<Integer> stackData;    private Stack<Integer> stackMin;    public MyStack1()    {        stackData = new Stack<Integer>();        stackMin = new Stack<Integer>();    }    /**     * 压入操作     * @param newNum     */    public void push(int newNum)    {        if(stackMin.isEmpty())        {            stackMin.push(newNum);        }        stackData.push(newNum);        if(newNum <= stackMin.peek())        {            stackMin.push(newNum);        }    }    /**     * 弹出操作     * @return     */    public int pop()    {        if(stackData == null)        {            throw new RuntimeException("Your Stack isEmpty");        }        int value = stackData.pop();        if(stackMin.peek() == value)        {            stackMin.pop();        }        return value;    }    public int getMin()    {        if(stackMin.isEmpty())        {            throw new RuntimeException("Your stack is Empty.");        }        return stackMin.peek();    }    public static void main(String[] args) {        MyStack1 stack1 = new MyStack1();        stack1.push(3);        stack1.push(2);        stack1.push(1);        int stack = stack1.pop();        int min = stack1.getMin();        System.out.println(stack + "" + min + "");    }}

看下书上是如何写的:

import java.util.Stack;public class MyStack1 {    private Stack<Integer> stackData;    private Stack<Integer> stackMin;    public MyStack1()    {        this.stackData = new Stack<Integer>();        this.stackMin = new Stack<Integer>();    }    public void push(int newNum)    {        if(this.stackMin.isEmpty())        {            this.stackMin.push(newNum);        }        else if(newNum <= this.getmin())        {            this.stackMin.push(newNum);        }        this.stackData.push(newNum);    }    public int pop()    {        if(this.stackData.isEmpty())        {            throw new RuntimeException("Your stack is Empty.");        }        int value = this.stackData.pop();        if(value == this.getmin())        {            this.stackMin.pop();        }        return value;    }    public int getmin()    {        if(this.stackMin.isEmpty())        {            throw new RuntimeException("Your stack is empty.");        }        return this.stackMin.peek();    }}

可以看出我写的不规范,pop操作应该是if-else的关系。

书上给出第二种设计方案:


其实差不多,就是在push操作的时候,如果stackData压入的数据大于等于stackMin的顶部元素的时候,StackMin重复压入顶部元素,这样,pop的时候,每次MinStack都弹出就可以了。

代码如下:

import java.util.Stack;public class MyStack2 {    private Stack<Integer> stackData;    private Stack<Integer> stackMin;    public MyStack2()    {        this.stackData = new Stack<Integer>();        this.stackMin = new Stack<Integer>();    }    public void push(int newNum) {        if (this.stackMin.isEmpty()) {            this.stackMin.push(newNum);        } else if (newNum < this.getmin()) {            this.stackMin.push(newNum);        }        else {            int newMin = this.stackMin.peek();            this.stackMin.push(newMin);        }        this.stackData.push(newNum);    }    public int pop() {        if (this.stackData.isEmpty()) {            throw new RuntimeException("Your stack is Empty.");        }        this.stackMin.pop();        return this.stackData.pop();    }    public int getmin() {        if (this.stackMin.isEmpty()) {            throw new RuntimeException("Your stack is empty.");        }        return this.stackMin.peek();    }}

代码在我的Github上有,欢迎下载查看。

https://github.com/GeniusVJR/Algorithm-Optimal-Solution

1 0