LeetCode Top 100 Liked Questions 239. Sliding Window Maximum (Java版; Hard)

welcome to my blog

LeetCode Top 100 Liked Questions 239. Sliding Window Maximum (Java版; Hard)

题目描述
Given an array nums, there is a sliding window of size k which is moving from the very left of the array to 
the very right. You can only see the k numbers in the window. Each time the sliding window moves right by 
one position. Return the max sliding window.

Example:

Input: nums = [1,3,-1,-3,5,3,6,7], and k = 3
Output: [3,3,5,5,6,7] 
Explanation: 

Window position                Max
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7
Note: 
You may assume k is always valid, 1 ≤ k ≤ input array's size for non-empty array.

Follow up:
Could you solve it in linear time?
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int n = nums.length;
        int[] res = new int[n-k+1];
        int p = 0;
        LinkedList<Integer> queue = new LinkedList<>();
        for(int i=0; i<n; i++){
            while(!queue.isEmpty() && nums[i] > nums[queue.peekLast()]){
                queue.pollLast();
            }
            queue.add(i);
            if(i-queue.peek()>=k){
                queue.poll();
            }
            if(i+1>=k){
                res[p++] = nums[queue.peek()];
            }
        }
        return res;
    }
}
第一次做; 队列中存储的是元素的索引, 因为索引含有更多的信息, 既可以找到元素值, 又能和滑窗的边界进行比较从而确定队首元素是否还在滑窗内;滑窗的左右边界: 右边界就是i, 左边界是i-k+1
import java.util.LinkedList;

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        //
        if(nums==null||nums.length==0)
            return new int[]{};
        //一共有n-k+1个滑动窗口
        int[] res = new int[nums.length-k+1];
        //数组中每个元素都入队一次, 如果入队的元素比队尾元素大与等于,就先弹出队尾元素,直到队尾元素大于入队元素
        //或者队列为空,此时再压入当前待入队元素
        //细节:实际操作中,队列存储的是索引; 因为位置信息更有价值,既可以找到nums中的元素,又能判断当前的框是否过期
        LinkedList<Integer> queue = new LinkedList<>();
        for(int i=0; i<nums.length; i++){
            while(!queue.isEmpty() && nums[i] >= nums[queue.getLast()]){
                queue.pollLast();
            }
            //当前元素索引进队
            queue.add(i);
            //如果队列首元素小于滑窗的左边界, 需要弹出队首元素
            if(queue.getFirst() < i-k+1)
                queue.poll();
            //i==k-1时出现了第一个框, 记录该滑窗中的最大值
            if(i>=k-1){
                res[i-k+1] = nums[queue.getFirst()];
            }
        }
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值