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

题目:

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

要求:

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 stackData;
    private Stack stackMin;

    public MyStack1()
    {
        stackData = new Stack();
        stackMin = new Stack();
    }

    /**
     * 压入操作
     * @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 stackData;
    private Stack stackMin;

    public MyStack1()
    {
        this.stackData = new Stack();
        this.stackMin = new Stack();
    }

    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 stackData;
    private Stack stackMin;

    public MyStack2()
    {
        this.stackData = new Stack();
        this.stackMin = new Stack();
    }

    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

你可能感兴趣的:(算法,算法)