Java 使用linkedlist构建最小-最大堆栈

Java 使用linkedlist构建最小-最大堆栈,java,algorithm,data-structures,stack,nodes,Java,Algorithm,Data Structures,Stack,Nodes,问题 其思想是构造一个最小-最大堆栈,该堆栈可以在恒定时间内执行以下操作 推 流行音乐 偷看 getMinValue getMaxValue 我的方法 我的想法是,我已经创建了一个节点结构,它将存储自己的值以及插入时的最小值和最大值 因此,例如,当我向堆栈中插入值4时,由于head为null,节点会将min和max设置为自己的值。但是,如果插入时头部不为空,则我们将新节点值与头部最小值和最大值进行比较,例如,如果新节点值较小,则最小值将为其自身值,否则将采用头部的最小值。相同的逻辑用于维护最小值

问题

其思想是构造一个最小-最大堆栈,该堆栈可以在恒定时间内执行以下操作

  • 流行音乐
  • 偷看
  • getMinValue
  • getMaxValue
  • 我的方法

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

    因此,例如,当我向堆栈中插入值4时,由于head为null,节点会将min和max设置为自己的值。但是,如果插入时头部不为空,则我们将新节点值与头部最小值和最大值进行比较,例如,如果新节点值较小,则最小值将为其自身值,否则将采用头部的最小值。相同的逻辑用于维护最小值和最大值

    因此,在任何给定的时间,我们都可以窥视头部,得到堆栈在给定时间的最小值和最大值

    代码

      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;
        }
        }
    
    静态类MinMaxStack{
    节点头=空;
    类节点{
    整数值;
    节点下一步;
    最小整数;
    整数最大值;
    公共节点(整数val){
    this.value=val;
    }
    }
    公共整数peek(){
    返回head.value;
    }
    公共整数pop(){
    节点温度=头;
    if(head.next!=null){
    压头=下一个温度;
    temp.next=null;
    }否则{
    head=null;
    }
    返回温度值;
    }
    公共无效推送(整数){
    节点x=新节点(编号);
    if(head==null){
    水头=x;
    x、 最小值=x.0;
    x、 最大值=x.0;
    }否则{
    x、 min=x.valuehead.max?x.max:head.max;
    x、 下一个=头部;
    水头=x;
    }
    }
    公共整数getMin(){
    返回头.min;
    }
    公共整数getMax(){
    返回头最大值;
    }
    }
    
    问题

      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;
        }
        }
    

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

    我可以看到两件事可以解决:

    推送

    在这行:
    x.max=x.value>head.max?x、 max:head.max
    您正在将
    x.max
    重新分配到
    x.max
    ,请将其更改为:

    x.max=x.value>head.max?x、 值:head.max

    pop

    您只需要:

    public Integer pop() throws EmptyStackException {
      if (head == null) throw new EmptyStackException();
      Integer result = head.value;
      head = head.next;
      return result;
    }
    
    基本上,您是在弹出
    头部
    。 现在您可能想知道这是否会影响
    min
    max

    不会的。有三种情况:

  • 弹出前的当前
    head
    可以是
    min
  • 弹出前的当前
    head
    可以是
    max
  • 1和2

  • 在所有情况下,如果您删除
    ,其下一个节点已经包含次优的
    最小值
    最大值
    值,因为您在推送过程中正在更新这些值。

    还请共享正确和失败的测试用例。为什么每个节点都需要存储最小值/最大值?为什么列表不在自己的变量中跟踪最小值/最大值呢?@JonnyHenly那么这就违背了在恒定时间内获取最小值的想法。如果我们弹出过去是globalMin的值,我们需要知道新的globalMin,我们将不得不再次扫描整个列表。很好,大部分都是改进,真正的错误是x.max,应该是x.value。有道理,x.max是一个愚蠢的错误,是的,我认为我的弹出逻辑是错误的,现在我通过了所有测试用例。