• 剑指Offer59-II:队列最大值


    题目:https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof/

    题意:实现一个队列接口,使它能够在o(1)时间内获取队列中的最大值

    思路:双端队列。因为队列存在入队和出队的操作,所以队列中的最大值不是固定的。队列含有先进先出的特性,所以当一个元素入队后,当该元素是队列中的最大值,那么可以不考虑该最大值之前的元素,因为它们会比该元素早出队。因此,我们维护一个双端队列,每次元素入队时,先与队头元素比较,大于队头元素时,就替换队头元素;否则,与双端队列的队尾元素进行比较,当大于队尾元素时就出队,直到不大于队尾元素,将该元素入队。

    代码:

    public class Offer59 {
        private LinkedList<Integer> maxValue;
        private int[] queue;
        private int front, back;
        private final static int MAX_LENGTH = 10001;
        public Offer59() {
            queue = new int[MAX_LENGTH];
            front = back = 0;
            maxValue = new LinkedList<>();
        }
    
        public int max_value() {
            if(front == back) return -1;
            return queue[maxValue.peekFirst()];
        }
    
        public void push_back(int value) {
            queue[back] = value;
            if(maxValue.isEmpty()) {
                maxValue.offerLast(back);
            }
            else {
                if(value >= queue[maxValue.peekFirst()]){
                    maxValue.clear();
                    maxValue.offerLast(back);
                }else{
                    while (value > queue[maxValue.peekLast()]) {
                        maxValue.pollLast();
                    }
                    maxValue.offerLast(back);
                }
            }
            back = ((back+1) % MAX_LENGTH);
        }
    
        public int pop_front() {
            if(front == back) return -1;
            int t = queue[front];
            front = (front + 1) % MAX_LENGTH;
            if (maxValue.peekFirst() < front) {
                maxValue.pollFirst();
            }
            return t;
        }
    
        public static void main(String...args){
            Offer59 offer59 = new Offer59();
            offer59.push_back(5);
            System.out.println(offer59.max_value());
            offer59.push_back(1);
            System.out.println(offer59.max_value());
            offer59.push_back(2);
            System.out.println(offer59.max_value());
            System.out.println(offer59.pop_front());
            System.out.println(offer59.max_value());
            System.out.println(offer59.pop_front());
            System.out.println(offer59.pop_front());
            System.out.println(offer59.pop_front());
            System.out.println(offer59.max_value());
            offer59.push_back(4);
            System.out.println(offer59.pop_front());
            System.out.println(offer59.max_value());
    
            System.out.println(offer59.max_value());
        }
    }

    ps:题目中操作次数在[1, 10000]内,因此开了个整型数组作为队列,最后的内存消耗打败了92.46%的用户,说明这样做还是可以的。但时间消耗只打败了26.95%的用户,说明代码思路还不是最优。

  • 相关阅读:
    第六周总结
    《构建之法》读后感二
    移动端疫情展示
    第五周
    用python爬取疫情数据
    第四周
    疫情图表展示和时间查询
    wpf datagrid row height 行高自动计算使每行行高自适应文本
    c# 实现mysql事务
    c# 简单实现 插件模型 反射方式
  • 原文地址:https://www.cnblogs.com/liuyongyu/p/14041596.html
Copyright © 2020-2023  润新知