设计一个栈,出pop与push方法,还支持 min方法,可返回栈元素中的最小值

本文介绍了一种特殊栈的设计方案,该栈除了具备基本的push和pop功能外,还支持min方法,用于快速获取栈中当前的最小值。文章详细解释了如何通过辅助栈stackOfMin来实现在O(1)时间内完成min操作,同时保持push和pop操作的高效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设计一个栈,除pop与push方法,还支持min方法,可返回栈元素中的最小值。

push,pop和min三个方法的时间复杂度必须为O(1)

要保证min的时间复杂度为O(1), 那就不能每次通过遍历整个栈来获取最小值。假设这个栈初始为5:

5; 最小值为5; 压入7,栈变为

7,5;最小值为5; 压入3,栈变为

3,7,5; 最小值为3

 

这时弹出3,栈变为

7,5; 最小值为5; 弹出7, 栈变为

5; 最小值为5;

 

注意在7,5这个状态时,最小值都是5. 也就是说,如果我们能标记出栈的每个状态,那么可以直接取出最小值。可以用一个栈来保存最小值。

stack类的peek()方法,查看栈顶对象而不移除它

  1. /** 
  2.  * 思路:每个结点记录当前最小值。 
  3.  * 缺点:当栈很大时,每个元素都要记录 min,就会浪费大量空间。 
  4.  */  
  5. public class StackWithMin extends Stack<NodeWithMin>{  
  6.   
  7.       public static void main(String[] args) {  
  8.              // TODO Auto-generated method stub  
  9.   
  10.       }  
  11.         
  12.       public void push(int value){  
  13.              int newMin=Math. min(value , min());  
  14.              super.push( new NodeWithMin( value, newMin));              
  15.       }  
  16.         
  17.       public int min(){  
  18.              if( this.isEmpty())  
  19.                    return Integer. MAX_VALUE;  
  20.              else  
  21.                    return peek(). min;  
  22.       }  
  23. }  
  24.   
  25. class NodeWithMin{  
  26.       public int value;  
  27.       public int min;  
  28.         
  29.       public NodeWithMin( int value, int min){  
  30.              this. value= value;  
  31.              this. min= min;  
  32.       }  
  33. }

对于栈,实现其min方法很简单,就是每次push一个值的时候,对minValue进行维护:

if(value < minVlaue){
    minValue = value;
}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

每次调用min() 时直接返回minValue即可。但是,如果pop走的是minValue则需要遍历剩下的元素求最小值。所以这样无法满足O(1)的要求,我们需要额外的空间保存栈的每一个状态下的最小值。

正如上面陈述的,只要当push的值小于minValue时和pop的值等于minValue时才需要进行额外的操作,用额外的一个栈 stackOfMin来记录最小值的情况。当push的值小于minValue时,stackOfMin push新的最小值;pop的值等于minValue时,stackOfMin也相应地pop就行。

代码

package test1;

import java.util.Stack;

public class StackWithMin extends Stack<Integer>{

    private Stack<Integer> stackOfMin;

    public StackWithMin() { //存放最小值的栈  
        stackOfMin = new Stack<>();
    }

    public int min() {
        if(stackOfMin.isEmpty()){
            return Integer.MAX_VALUE;
        }else {
            return stackOfMin.peek();
        }
    }

    @Override
    public Integer push(Integer item) {
        if(item < min()){
            stackOfMin.push(item); //调用自身Stack的Push方法,而不是StackWithMin2的方法(sMin是Stack类)   
        }
        return super.push(item);
    }

    @Override
    public synchronized Integer pop() {
        if(this.peek() == min()){
            stackOfMin.pop();
        }
        return super.pop();
    }

    public static void main(String[] args) {
        StackWithMin stackWithMin = new StackWithMin();
        stackWithMin.push(19);
        System.out.println("The min is: "+stackWithMin.min());

        stackWithMin.push(15);
        System.out.println("The min is: "+stackWithMin.min());

        stackWithMin.push(17);
        System.out.println("The min is: "+stackWithMin.min());

        stackWithMin.pop();
        System.out.println("The min is: "+stackWithMin.min());

        stackWithMin.pop();
        System.out.println("The min is: "+stackWithMin.min());

        stackWithMin.push(30);
        System.out.println("The min is: "+stackWithMin.min());

        stackWithMin.push(1);
        System.out.println("The min is: "+stackWithMin.min());

        stackWithMin.push(4);
        System.out.println("The min is: "+stackWithMin.min());
    }

}

 

The min is: 19
The min is: 15
The min is: 15
The min is: 15
The min is: 19
The min is: 19
The min is: 1
The min is: 1

转载于:https://my.oschina.net/u/2822116/blog/789425

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值