LeeCode (Priority Queue) 239_ Maximum sliding window

LeeCode (Priority Queue) 239_ Maximum sliding window

Topic:
Given an integer array nums, a sliding window of size k moves from the leftmost side of the array to the rightmost side of the array. You can only see the k numbers in the sliding window. The sliding window only moves one position to the right at a time.

Returns the maximum value in the sliding window.

Example 1:

Input: nums = [1,3,-1,-3,5,3,6,7], k = 3
Output: [3,3,5,5,6,7]
Explanation:
The maximum position of the sliding window


[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]
Example 3:

Input: nums = [1,-1], k = 1
Output: [1,-1]
Example 4:

Input: nums = [9,11], k = 2
Output: [11]
Example 5:

Input: nums = [4,-2], k = 2
Output: [4]

prompt:

1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length

Source: LeetCode
Link: https://leetcode-cn.com/problems/sliding-window-maximum The
copyright is owned by LeetCode . For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.

Problem-solving idea:
calculate the number of windows as nums.length-k+1

Method one: priority queue

  • For finding the maximum value , we can quickly think of the priority queue, where the large root heap can help us maintain the maximum value of a set of elements in real time.
  • Initial: We put K elements into the priority queue, at this time the top of the heap is the first maximum value.
  • Moving the window: When we move the window, add the corresponding next element to the priority queue. At this time, the maximum value can no longer be in the area included in the current window, so delete the element until the maximum value found is in the window area. Inside.
  • Thinking that we want to delete the elements that are not in the window in the priority queue in real time, we should put each element in the priority queue at the same time as its corresponding subscript.

Java code:

import java.util.Comparator;
import java.util.PriorityQueue;

public class 滑动窗口最大值 {
    
    
	public int[] maxSlidingWindow(int[] nums, int k) {
    
    
		int num = nums.length;
		PriorityQueue<int[]> pq = new PriorityQueue<int[]>(new Comparator<int[]>() {
    
    
			@Override
			public int compare(int[] pair1, int[] pair2) {
    
    
				// TODO Auto-generated method stub
				return pair1[0] != pair2[0] ? pair2[0]-pair1[0] : 0;
			}
		});
		
		for(int i=0;i<k;i++){
    
    
			pq.offer(new int[]{
    
    nums[i],i});
		}
		
		int[] ans = new int[num-k+1];
		ans[0] = pq.peek()[0];
		for(int i = k;i < num;i++){
    
    
			pq.offer(new int[]{
    
    nums[i],i});
			while(pq.peek()[1]<=i-k){
    
    
				pq.poll();
			}
			ans[i-k+1]=pq.peek()[0];	
		}
		
		return ans;
	}
}

Method 2: Monotonic Queue
We maintain a deque in which the subscripts of the elements of the array are arranged in a monotonously decreasing order according to their corresponding values.
Every time we put a value in the queue, we only need to consider whether the value is greater than the value at the end of the queue, if not, it will not be the maximum value. If it is greater than the value of the end of the queue, the value of the end of the queue is popped out, and then judged, until the queue is empty or the value is less than the value of the current end of the queue, the value is put into it.

Take the head of the queue (the subscript corresponding to the maximum value) to determine whether it is out of bounds (the subscript is not in the window), and get the answer.

import java.util.Comparator;
import java.util.Deque;
import java.util.LinkedList;
import java.util.PriorityQueue;

public class 滑动窗口最大值 {
    
    
	 public int[] maxSlidingWindow(int[] nums, int k) {
    
    
		 int n = nums.length;
		 Deque<Integer> deque = new LinkedList<>();
		 
		 //初始化队列
		 for(int i=0;i<k;i++){
    
    
			 while(!deque.isEmpty() && nums[i]>nums[deque.peekLast()]){
    
    
				 deque.pollLast();
			 }
			 deque.offerLast(i);
		 }
		 
		 int[] ans = new int[n-k+1];
		 
		 ans[0] = nums[deque.pollFirst()];
		 
		 for(int i=k;i<n;i++){
    
    
			 while(!deque.isEmpty() && nums[i]>nums[deque.peekLast()]){
    
    
				 deque.pollLast();
			 }
			 deque.offerLast(i);
			 
			 while(deque.peekFirst()<=i-k){
    
    
				 deque.pollFirst();
			 }
			 
			 ans[i-k+1] = nums[deque.peekFirst()];
		 }
		return ans;
	 }
}

Guess you like

Origin blog.csdn.net/u013456390/article/details/112556658