面试题59 - I. 滑动窗口的最大值 优化暴力+优先队列

#面试题59 - I. 滑动窗口的最大值

难度:简单 同题:239. 滑动窗口最大值
题目描述
面试题59 - I. 滑动窗口的最大值 优化暴力+优先队列_第1张图片
解题思路

1、优化的暴力法

这道题暴力法应该是挺简单的,在普通的暴力法基础上还存在优化的空间。
如果下一个值大于上个区间的最大值,那么新区间最大值肯定是nums[i];
还可以把上个区间内的最大值下标记录下来,如果滑动窗口之后最大值还在新区建立,就只要比较最右边新增值和上一个最大值。思路都差不多,就是减少向前搜寻找最大值的次数。

public int[] maxSlidingWindow(int[] nums, int k) {
  	int n = nums.length;
  	int []re = new int[n-k+1];
  	for (int i = 0; i < n; i++) {  
   		//先找出第一个区间内的最大值
   		if(i < k) {
    			re[0] = Math.max(re[0], nums[i]);
   		}
   		else {
    		//如果下一个值大于上个区间的最大值,那么新区间最大值肯定是nums[i]
    			re[i-k+1] = nums[i];
    			if(nums[i] < re[i-k]){  //否则暴力向前搜寻
     				int j = 0;
     				while(j < k) {
      					re[i-k+1] = Math.max(re[i-k+1], nums[i-j++]);
     				}
    			}
   		}
  	}
  	return re;
    }

面试题59 - I. 滑动窗口的最大值 优化暴力+优先队列_第2张图片

2、再次优化的暴力法

再次优化了一下,找到了比较次数更少的办法!!!
分析发现,只有最大元素在上个区间左边端点被弹出的时候,才需要向前搜寻比较,否则只需要比较新右端点和上个最大值。这样大大减少了向前搜寻的次数。

public int[] maxSlidingWindow(int[] nums, int k) {
  	if(k <= 1)
            	return nums;
  	int n = nums.length;
  	int []re = new int[n-k+1];
  	for (int i = 0; i < n; i++) {  
   		//先找出第一个区间内的最大值
   		if(i < k) {
    			re[0] = Math.max(re[0], nums[i]);
   		}
  	 	else {
    			if(re[i-k] == nums[i-k]){  //如果最大值被弹出,暴力向前搜寻
     			int j = 0;
     			while(j < k) {
      				re[i-k+1] = Math.max(re[i-k+1], nums[i-j++]);
     			}
    		}
    		//如果下一个值大于上个区间的最大值,那么新区间最大值肯定是nums[i]
    			else {
     				re[i-k+1] = Math.max(re[i-k], nums[i]);
    			}
   		}
  	}
  return re;
    }

面试题59 - I. 滑动窗口的最大值 优化暴力+优先队列_第3张图片

3、优先队列

优先队列,就是队列里的元素总是维持有序状态。
这个是评论里面一个人写的,虽然看起来代码很短,但是讲道理其实和暴力法差不多,只不过用优先队列来代替手动找最大值。。。。

public int[] maxSlidingWindow1(int[] nums, int k) {
  	PriorityQueue<Integer> q = new PriorityQueue<>((i, j) -> nums[j] - nums[i]);  //队里面按大小关系存放对应下标
        int n = nums.length;
        int[] res = new int[n - k + 1];
        int left = 0;
        for (int i = 0; i < k; i++) {
   		q.offer(i);
  	}
        res[0] = nums[q.peek()];
        for (int i = k; i < n; i++) {
         	q.remove(left ++);
            	q.offer(i);
            	res[i - k + 1] = nums[q.peek()];
  	}
        return res;
    }

面试题59 - I. 滑动窗口的最大值 优化暴力+优先队列_第4张图片

你可能感兴趣的:(力扣刷题笔记)