1、设计一个有getMin功能的栈

题目:

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

要求:

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

解法:

设计两个普通栈来构造这个特殊栈,其中一个普通栈dataStack维持正常的出栈入栈操作,另一个栈minStack存储每一步出栈入栈的特殊栈内的最小值。

解法1

出栈的操作稍复杂一些。

import java.util.Stack;

public class getMinStack1 {
    private Stack<Integer> dataStack;
    private Stack<Integer> minStack;

    public getMinStack1() {
        this.dataStack = new Stack<Integer>();
        this.minStack = new Stack<Integer>();
    }

    //压栈分析:
    //dataStack维持正常压栈操作
    //minStack为空或者当前需入栈元素小于等于栈顶元素时入栈,小于等于是为了和出栈操作一一对应。
    public void push(Integer newNum) {
        if(this.minStack.isEmpty() || newNum <= this.minStack.peek()){
            this.minStack.push(newNum);
        }
        this.dataStack.push(newNum);
    }

    //出栈分析:首先判断栈内是否有元素,没有抛出异常。
    //dataStack栈正常出栈,minStack当dateStack出栈元素对应时出栈,这里也解释了为什么入栈操作也要入栈等于元素
    public Integer pop() {
        if(this.dataStack.isEmpty()){
            throw new RuntimeException("Your stack is empty! Please check!");
        }
        Integer value = this.dataStack.pop();
        if(value == this.getMin()){
            this.minStack.pop();
        }
        return value;
    }

    //直接获取minStack的栈顶元素即是栈中最小值
    public Integer getMin() {
        if(this.minStack.isEmpty()){
            throw new RuntimeException("Your stack is empty!");
        }
        return this.minStack.peek();
    }
}

在这里插入图片描述

解法2

入栈的操作稍复杂一些。

import java.util.Stack;

public class getMinStack2 {
    private Stack<Integer> dataStack;
    private Stack<Integer> minStack;

    public getMinStack2() {
        this.dataStack = new Stack<Integer>();
        this.minStack = new Stack<Integer>();
    }

    //压栈操作:
    //压栈栈空时,直接入栈。
    //然后比较入栈元素和minStack的栈顶元素(就是当前栈中最小值),minStack入栈最小者。
    //dataStack正常压栈。
    public void push(Integer newNum){
        if(this.minStack.isEmpty()){
            this.minStack.push(newNum);
        }else if(this.getMin() <= newNum){
            this.minStack.push(this.getMin());
        }else{
            this.minStack.push(newNum);
        }
        this.dataStack.push(newNum);
    }

    //出栈操作:
    //判断是否栈空,栈空抛出异常。
    //因为入栈操作缘故,出栈直接保持两栈同步出栈即可。
    public Integer pop(){
        if(this.dataStack.isEmpty()){
            throw new RuntimeException("Your stack is empty!");
        }
        this.minStack.pop();
        return this.dataStack.pop();
    }

    //minStack的栈顶元素即是当前栈中的最小值。
    public Integer getMin(){
        if(this.minStack.isEmpty()){
            throw new RuntimeException("Your stack is Empty!");
        }
        return this.minStack.peek();
    }
}

在这里插入图片描述

测试

import StackQueue.getMinStack.getMinStack1;
import StackQueue.getMinStack.getMinStack2;

public class getMinStackTest {
    public static void main(String[] args) {

        getMinStack1 stack1 = new getMinStack1();
        stack1.push(3);
        System.out.println(stack1.getMin());
        stack1.push(4);
        System.out.println(stack1.getMin());
        stack1.push(5);
        System.out.println(stack1.getMin());
        stack1.push(1);
        System.out.println(stack1.getMin());
        System.out.println(stack1.pop());
        System.out.println(stack1.pop());
        System.out.println(stack1.getMin());
        stack1.push(2);
        System.out.println(stack1.getMin());
        stack1.push(1);
        System.out.println(stack1.getMin());

        System.out.println("------------------------------");

        getMinStack2 stack2 = new getMinStack2();
        stack2.push(3);
        System.out.println(stack2.getMin());
        stack2.push(4);
        System.out.println(stack2.getMin());
        stack2.push(5);
        System.out.println(stack2.getMin());
        stack2.push(1);
        System.out.println(stack2.getMin());
        System.out.println(stack2.pop());
        System.out.println(stack2.pop());
        System.out.println(stack2.getMin());
        stack2.push(2);
        System.out.println(stack2.getMin());
        stack2.push(1);
        System.out.println(stack2.getMin());
    }
}

运行结果:
分别对两个方法进行测试,得到一致的结论。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值