剑指offer java day27 栈与队列

T1 59 - I. 滑动窗口的最大值

滑动窗口每次移动元素的增添符合队列先进先出的特点

创建一个队列保证

1.仅包含滑动窗口的元素

2.每次添加元素队列里小于新增加元素则删除

QueueDeque
添加元素到队尾add(E e) / offer(E e)addLast(E e) / offerLast(E e)
取队首元素并删除E remove() / E poll()E removeFirst() / E pollFirst()
取队首元素但不删除E element() / E peek()E getFirst() / E peekFirst()
添加元素到队首addFirst(E e) / offerFirst(E e)
取队尾元素并删除E removeLast() / E pollLast()
取队尾元素但不删除E getLast() / E peekLast()
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if(nums.length==0 || k==0) return new int[0]; //空值处理
        Deque<Integer> queue = new LinkedList<Integer>(); //滑动窗口队列
        int[] res = new int[nums.length-k+1]; //每次滑动后的最大值
        //为形成窗口
        for(int i=0;i<k;i++){
            //队列中小于新增元素删除
            //保证队列单调不增,队首最大
            while(!queue.isEmpty() && queue.peekLast() < nums[i]) 
                queue.removeLast();
            queue.addLast(nums[i]);
        }
        res[0] = queue.peekFirst();

        //形成滑动窗口
        for(int i=k;i<nums.length;i++){
            //更新滑动窗口,需删除滑动窗口原来的第一位
            //由于须保证每次小于新增元素要删去
            //则原来的第一位可能在之前已经删除了,所以一判断一下
            if(queue.peekFirst() == nums[i-k])
                queue.removeFirst();
            //队列中小于新增元素删除
             //保证队列单调不增,队首最大 
            while(!queue.isEmpty() && queue.peekLast()<nums[i]) 
                queue.removeLast();
            queue.addLast(nums[i]);
            res[i-k+1] = queue.peekFirst();
        }
        return res;
    }
}

T2 59 - II. 队列的最大值

和上一题核心思路一致

class MaxQueue {
    Queue<Integer> queue; //存放数字的入队顺序
    Deque<Integer> deque; //保证单调不减双端队列,快速拿去最大值(队首)
    public MaxQueue() {
        queue = new LinkedList<Integer>();
        deque = new LinkedList<Integer>();
    }
    
    public int max_value() {
        //双端队列非空弹出队首否则-1
        return deque.isEmpty() ? -1: deque.peekFirst();
    }
    
    public void push_back(int value) {
        queue.add(value);
        //双端保证单调不减
        //每次小于新增元素的双端队列元素删除
        while(!deque.isEmpty() && deque.peekLast()<value)
            deque.removeLast();
        deque.addLast(value);
    }
    
    public int pop_front() {
        if(queue.isEmpty()) return -1; 
        //由于保持单调不减的双端队列
        //可能在添加新元素时删除了pop_front需求队首
        //所以和存放数字顺序队列的队首做比较
        //相同则同时出队,不同则双端不处理 equals比较地址和值
        if(queue.peek().equals(deque.peekFirst()))
            deque.removeFirst();
        return queue.remove();

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值