剑指offer计划27(栈与队列困难)---java

1.1、题目1

剑指 Offer 59 - I. 滑动窗口的最大值

1.2、解法

解题思路:(来自作者bigbeats)

相当于维护一个最大队列(队头元素最大,向队尾非严格递减)

在未形成窗口前,先构造完整窗口。
在形成窗口后,移动窗口:

判断即将失去的这个左边界值是否是最大值,如果是需要从最大队列中删除这个最大值。
再让队列尾部开始与即将加入的右边界值做对比,如果队列尾部元素大于或等于这个元素,则将这个元素加入尾部,反之将尾部元素删除。

以上两步操作保证队列的顺序是非严格递减的,即队头存放最大值。且队列中元素的生命周期都在对应的窗口期内。

1.3、代码


class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if(nums == null || k == 0) return new int[]{};
        Deque<Integer> q = new LinkedList<>();

        // 形成最初的窗口
        for(int i = 0;i <= k - 1;++i){
            while(!q.isEmpty() && q.peekLast() < nums[i]){
                q.removeLast();
            }
            q.offerLast(nums[i]);
        }
        int[] res = new int[nums.length - k + 1];
        res[0] = q.peekFirst();
        if(nums[0] == q.peekFirst()){
            q.removeFirst();
        }         

        // 窗口已经形成
        for(int i = k;i <= nums.length -1;++i){           
            while(!q.isEmpty() && q.peekLast() < nums[i]){
                q.removeLast();
            }
            q.offerLast(nums[i]);            
            res[i-k+1] = q.peekFirst();
            if(nums[i-k+1] == q.peekFirst()){
                q.removeFirst();
            }             
        }
        return res;
    }
}



2.1、题目2

剑指 Offer 59 - II. 队列的最大值

2.2、解法

这里用两个队列来解决,queue用来存放当前放置的内容,deque来存放一定数量的大数
最大值则直接取queue降序的头,push时,则将deque中小于它的数去掉,将该值添加到队列末尾。
pop时,判断deque的头是否是推出的头,是的话也将该数值推出。

2.3、代码

class MaxQueue {
    Queue<Integer> q;
    Deque<Integer> d;

    public MaxQueue() {
        q = new LinkedList<Integer>();
        d = new LinkedList<Integer>();
    }
    
    public int max_value() {
        if (d.isEmpty()) {
            return -1;
        }
        return d.peekFirst();
    }
    
    public void push_back(int value) {
        while (!d.isEmpty() && d.peekLast() < value) {
            d.pollLast();
        }
        d.offerLast(value);
        q.offer(value);
    }
    
    public int pop_front() {
        if (q.isEmpty()) {
            return -1;
        }
        int ans = q.poll();
        if (ans == d.peekFirst()) {
            d.pollFirst();
        }
        return ans;
    }
}



posted @ 2021-09-27 11:32  程序员khaos  阅读(98)  评论(0编辑  收藏  举报