力扣239. 滑动窗口最大值

这个题我做了好久,人都傻了。我自己写得也很混乱,你要是喷那就是你对。
看之前先看一下代码随想录,看不懂再来看一下我的分析,链接:代码随想录
第一是MyQueue的pop和push函数没搞懂
这个题目要保证在peek的时候取出的就是窗口中的最大数,那就要保证此时队列里的元素既是窗口里的元素,而且要保持递减。
实现就在pop函数和push函数的实现里。
push: 如果当前队列为空,则直接入队;否则判断队尾的元素是否比val大,如果大,则直接入队,否则队尾出队直到队尾比val大或者为空,然后再入队。这样就保证了队列保持递减。
pop: 如果当前退出窗口的元素就是队首的元素,则直接出队即可;如果不是队首的元素,则说明该元素已经不在队列里,之前就已经出了,不用出队。
为什么说该元素不是队首元素就说明已经出队了?因为所有元素都是从队尾进队列的,且只要小于入队元素的元素都会出队,则队列里的元素不光递减,而且顺序和入队顺序一致,所以要么该元素最大在队首,要么已经出队,不可能在队列里还不是第一个,因为若有比他更大的元素也即更早入队的元素在他前面,在之前的操作里一定已经出队了。(说得很混乱,原谅我,我也只是给自己做个笔记,呜呜呜……)

第二是deque的函数没搞懂(之前没有接触过)
根据第一条里的分析,要弄清楚。
pop: 是从队首出,则是pollFirst()
push: 将队尾小于val的元素全出,所以是pollLast(),入也是从队尾入,所以是offerLast(val)。
每个函数是First还是Last千万搞清楚!!!

代码如下:

class MyQueue{
    Deque<Integer> deque = new LinkedList<>();
    void pop(int val){//val原来是value啊
        if(val == deque.peekFirst()){
            deque.pollFirst();
        }
    }
    void push(int val){
        while(!deque.isEmpty() && deque.peekLast() < val){
          deque.pollLast();
        }
        deque.offerLast(val);
    }
    int peek(){
        return deque.peekFirst();
    }
}
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        MyQueue queue = new MyQueue();
        int[] res = new int[nums.length - k + 1]; 
        int j = 0;
        for(int i = 0; i < k; i++){
            queue.push(nums[i]);
        }
        res[j++] = queue.peek();
        for(int i = k; i < nums.length; i++){
            queue.pop(nums[i - k]);
            queue.push(nums[i]);
            res[j++] = queue.peek();
        }
        return res;
    }
}

你可能感兴趣的:(leetcode,算法,职场和发展)