#239 Sliding Window Maximum

Description

You are given an array of integers 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.

Examples

Example 1:

Input: nums = [1,3,-1,-3,5,3,6,7], 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

Example 2:

Input: nums = [1], k = 1
Output: [1]

Constraints:

1 <= nums.length <= 1 0 5 10^5 105
− 1 0 4 -10^4 104 <= nums[i] <= 1 0 4 10^4 104
1 <= k <= nums.length

思路

作为一道hard,他一定不能用暴力的方式求解,我在solution里面看到了一很很很精妙的方法。
他首先根据k的大小把nums进行分段,以Example1为例,就分为
1 | 3 -1 -3 | 5 3 6 | 7
如此划分之后,再从左到右依次计算每个段落中的最大值
left = 1 | 3 3 3 | 5 5 6 | 7
再从右到左以此计算每个段落中的最大值
right = 1 | 3 -1 -3 | 6 6 6 | 7
当我们要获取以 i位置为开头的最大值时候,只需要比较 right[i]left[i+k-1],然后选取较大的那个即可。

可以这么做的原因在于,通过k来划分之后,一个sliding window最多会跨越两个段落,还是以example1为例,i = 3时,需要判定的是[-3 5 3],跨越的就是[3 -1 -3][5 3 6],对这两个段落来说,我们之前计算的 right[3] = -3表示段落1[3 -1 -3]中,max([-3])的值,left[3 + 3 - 1] = left[5] = 5表示段落2[5 3 6]中,max([5, 3])的值,那么max(max([-3]), max([5, 3]))就是 max([-3, 5, 3]),从而得到sliding window的max值

代码

class Solution {
    public int[] maxSlidingWindow(int[] arr, int k) {
        int n = arr.length;

		int[] left = new int[n];
		int[] right = new int[n];
        
		left[0] = arr[0];
		for(int i = 1; i < n; i++) {
			left[i] = i % k == 0? arr[i]: Math.max(left[i - 1], arr[i]);
		}
        
        right[n - 1] = arr[n - 1];
        for (int i = n - 2; i >= 0; i--) {
            right[i] = i % k == 0? arr[i]: Math.max(right[i + 1], arr[i]);
        }
        
		int[] res = new int[n - k + 1];
		for(int i = 0; i < n - k + 1; i++)
			res[i] = Math.max(right[i], left[i + k - 1]);
        
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值