使用链表构建最小最大堆栈

Posted

技术标签:

【中文标题】使用链表构建最小最大堆栈【英文标题】:Build a min max stack using a linkedlist 【发布时间】:2019-12-29 02:50:22 【问题描述】:

问题

想法是构造一个MIN MAX堆栈,可以在恒定时间内完成以下操作。

    推送 流行音乐 偷看 获取最小值 获取最大值

我的方法

我的想法是我创建了一个节点结构,它将存储自己的值以及插入时的最小值和最大值。

因此,例如,当我将值 4 插入堆栈时,因为头部为空,节点会将最小值和最大值设置为其自己的值。但是,如果在插入时头部不为空,那么我们会比较新节点值和头部最小值和最大值,如果新节点值较小,那么最小值将是它自己的值,否则它将采用在头部的最小值上。应用相同的逻辑来维护最小值和最大值。

因此,在任何给定时间,我们都可以查看头部并获取该给定时间堆栈的最小值和最大值。

代码

  static class MinMaxStack 
        Node head = null;

        class Node
            Integer value;
            Node next;
            Integer min;
            Integer max;

            public Node(Integer val)
                this.value = val;
            
        

    public Integer peek() 
            return head.value;
        
    public Integer pop() 
             Node temp = head;
            if(head.next != null)
                head = temp.next;
                temp.next = null;
            else
                head = null;
            
            return temp.value;
    


    public void push(Integer number) 
            Node x = new Node(number);
            if(head == null)
                head = x;
                x.min = x.value;
                x.max = x.value;
            else
                x.min = x.value < head.min ? x.value : head.min;
                x.max = x.value > head.max ? x.max : head.max;
                x.next = head;
                head = x;
            
    


    public Integer getMin() 
      return head.min;
    


    public Integer getMax() 
      return head.max;
    
    

问题

我知道还有其他方法可以实现这一点,但我决定采用链表路线。出于某种原因,我的代码未能通过测试用例,所以我不确定我是否做错了什么。我只是想确保我的逻辑没有问题,因为我无法解决这个问题。

【问题讨论】:

还请分享正确和失败的测试用例。 为什么每个节点都需要存储一个最小值/最大值?为什么列表不只跟踪其自身变量中的最小值/最大值? @JonnyHenly 那么这将违反能够在恒定时间内获得最小值的想法。如果我们弹出曾经是 globalMin 的值,我们需要知道新的 globalMin 并且我们必须再次扫描整个列表。 【参考方案1】:

我可以看到两点可以修复:

push:

在这一行:x.max = x.value &gt; head.max ? x.max : head.max; 您将 x.max 重新分配给 x.max,将其更改为:

x.max = x.value &gt; head.max ? x.value : head.max;

pop:

这里只需要:

public Integer pop() throws EmptyStackException 
  if (head == null) throw new EmptyStackException();
  Integer result = head.value;
  head = head.next;
  return result;

基本上你正在弹出head。 现在你可能想知道这是否会影响minmax

不会的。分三种情况:

    弹出前的当前head 可能是min 值。 弹出前的当前head 可能是max 值。 1 和 2。

在所有情况下,如果您删除 head,它的下一个节点已经包含次优的 minmax 值,因为您在推送期间更新它们。

【讨论】:

很好,大部分都是改进,真正的错误是 x.max 应该是 x.value。 有道理,x.max 是一个愚蠢的错误,是的,我认为我的流行逻辑是错误的,现在我通过了所有测试用例。

以上是关于使用链表构建最小最大堆栈的主要内容,如果未能解决你的问题,请参考以下文章

二叉堆

SPL数据结构2-Heap,最大堆,最小堆

最小堆(优先队列)基本概念,即一个完整建立,插入,删除代码

浅谈堆栈队列

查找堆栈中的最大值和最小值

最大堆,最小堆及堆排序