leetcode【高级】 滑动窗口最大值 java

不打扰是莪最后的温柔 提交于 2019-12-14 12:14:58

题干

给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。

示例:

输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7] 
解释: 

  滑动窗口的位置                最大值
---------------               -----
[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
 

提示:

你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。

进阶:

你能在线性时间复杂度内解决此题吗?

想法

自然而然地有几个想法:
每移动一次,将这个移动后位置的数的大小和窗口中最大值比较,如果它比最大值大,那么将它更新为最大值。
否则仅仅是放到滑动窗口中
另一个点是:窗口大小有限,需要适时的删除已经过期的元素。

Java代码

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
         if (nums.length == 0) {
            return new int[0];
        }

        int[] maxes = new int[nums.length - k + 1];

        int i, j;
        int maxPos = -1;

        for (i = 0; i <= nums.length - k; ++i) {
		    // Ending index of the current window
            j = i + k - 1;

            // new element >= max of last window
            // that means new element is max in the two windows
			// here using >= to make maxPos stay in the windows for a longer time
            if (maxPos != -1 && nums[j] >= nums[maxPos]) {
                maxPos = j;
                maxes[i] = nums[maxPos];
            }
            // new element < max of last window
            // AND the max of last window is also in this window
			// => it means the max of the last window is still the max of this window
            else if (i <= maxPos) {//因为i比maxpo小,其实就是之前已经比较过了,所以nums[i]也比nums[maxpo]小
                maxes[i] = nums[maxPos];
            }
            // new element < max of last window
            // AND the max of last window is not in this window
			// So we do not know which element is the max in this window, we have to scan the window to find it
            else {
                int maxWindow = Integer.MIN_VALUE;
                int maxPosWindow = 0;
                for (int z = i; z <= j; ++z) {
                    if (nums[z] > maxWindow) {
                        maxPosWindow = z;
                        maxWindow = nums[z];
                    }
                }
                maxPos = maxPosWindow;
                maxes[i] = nums[maxPos];
            }
        }
        return maxes;
    }
}
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if (nums==null||nums.length==0||k<=0){
            return new int[0];
        }
        int len=nums.length;
        int[] res=new int[len-k+1];
        LinkedList<Integer>  dQueue=new LinkedList<>();
        
        for(int i=0;i<len;i++){
            //比当前元素小的都弹出
           while(!dQueue.isEmpty()&&nums[i]>nums[dQueue.getLast()]){
               dQueue.removeLast();
           }//加索引,记录位置
            dQueue.addLast(i);
            if(i-dQueue.getFirst()>=k){
                dQueue.removeFirst();
            }//过了第一次填满之后,就每移动一次更新一次最大
            if(i>=k-1){
                res[i-k+1]=nums[dQueue.getFirst()];
            }
            
        }
        
    return res;}
}
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if(nums.length==0) return new int[0];
    	int res[]=new int[nums.length-k+1];
    	int max=Integer.MIN_VALUE;
    	int maxIndex=-1;
    	for(int i=0;i<=nums.length-k;i++){
    		if(i<=maxIndex){
    			if(nums[i+k-1]<max){//只与新来的比
        			res[i]=max;
    			}else{
    				max=nums[i+k-1];
    				maxIndex=i+k-1;
    				res[i]=max;
    			}

    		}else{//重新寻找
        		max=Integer.MIN_VALUE;
        		for(int j=i;j<i+k;j++){
        			if(nums[j]>max){
        				max=nums[j];
        				maxIndex=j;
        			}
        		}
        		res[i]=max;
    		}

    		
    	}
    	return res;
        
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!