Stack(篇2)设计一个栈能在O(1)的时间和O(1)的空间getMin()

47 篇文章 37 订阅
22 篇文章 1 订阅

在上一篇文章中实现了
使用O(1)时间和O(n)的额外空间的方法getMin()。Stack(篇3)设计一个栈能够在O(1)的时间内getMin
在本文中,讨论了一种支持O(1)额外空间的最新方法。我们定义一个变量minEle,它存储堆栈中的当前最小元素。现在的问题是如何处理最小元素被删除的情况。为了处理这个,我们将“2x-minEle”推入堆栈而不是x,以便可以使用当前的minEle检索先前的最小元素,并将其值存储在堆栈中。

以下是算法的核心部分。

Push(x)
①如果堆栈为空,则将x插入堆栈,并使minEle等于x。
②如果堆栈不为空,请将x与minEle进行比较。出现两种情况:
③如果x大于或等于minEle,只需插入x。
④如果x小于minEle,则将(2 * x - minEle) 压到栈中,将minEle的值更新为 x。

Pop():
①从顶部移除元素 将删除的元素设为y。出现两种情况:
②如果y大于minEle,则堆栈中的最小元素仍为minEle。
③如果y小于或等于minEle,则最小元素现在变为(2 * minEle - y),因此更新minEle = 2 * minEle - y。
得到了前一个minEle。

重点:
①如果到目前为止,堆栈不保持元素的实际值。
②实际最小元素始终存储在minEle中
例如数组:{4,2,1,1,5,-1}
插入
下图中黄色部分是放到栈中的值,绿色部分是当前minEle的值变化情况实际上minEle的值并不需要栈来保存,只需要一个变量来保存每次最顶上的就可以。红色部分是压栈的顺序。
这里写图片描述

①当栈为空时,放入的第一个元素赋值给 minEle。将4压入栈中当前最小值 minEle=4。

这里写图片描述

② 遍历到2时,将2与minEle比较,2<minEle, 此时将 2*2-minEle=0 压入栈中,minEle=2。

这里写图片描述

③ 遍历到1时,将1与minEle=2比较,1<minEle,此时将 1*2-minEle=0 压入栈中,minEle=1。

这里写图片描述

这里写图片描述

④ 遍历到5时,将5与minEle=1比较,5>minEle,直接压栈,minEle不变。

这里写图片描述
⑤遍历到-1时,将-1与minEle=1比较,-1<minEle,此时将 -1*2-minEle=-3压入栈中,minEle=-1。


删除

这里写图片描述

①删除栈顶元素 -3,比较-3与minEle的值,发现 -3<minEle=-1,此时原来栈顶元素应该是:-3-2*minEle=-1 , 更新minEle=2*minElen+3=1.

这里写图片描述

②删除栈顶元素5,5>minEle,直接删除。


代码


package Stack;

import java.util.Stack;

public class Mystack {
    public static int minEle=0;
    Stack< Integer> stack;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Mystack stack=new Mystack(new Stack<Integer>());
        stack.push(3);
        stack.push(4);
        stack.push(2);
        stack.push(1);
        stack.push(5);
        System.out.println(stack.getMin());
        stack.pop();
        stack.pop();
        System.out.println(stack.getMin());
        stack.pop();
        stack.pop();
        System.out.println(stack.getMin());
    }

    public Mystack(Stack<Integer> stack) {
        this.stack = stack;
    }

    public void push(int num)
    {

        if(stack.isEmpty())
        {
            minEle=num;
            stack.push(num);
        }
        else {
            if(minEle<num)
                stack.push(num);
            else {              
                stack.push(2*num-minEle);               
                minEle=num;
            }
        }

    }
    public int pop()
    {
        if(!stack.isEmpty())
        {
          if(stack.peek()<=minEle)
          {
              minEle=2*minEle-stack.peek();
          }
          return stack.pop();                 
        }
        else {
            return 0;
        }               
    }
    public  int getMin()
    {
        return minEle;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值