Description:
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.
Solution1:
We can use a PriorityQueue to maintain all the current data in sliding window. So the priority queue has a size of k. Everytime it moves to the next step, just remove the first of the list then add a new one. And remember to write a new comparator with a bigger number has higher priority, so the peek of priority queue can be the largest of current window.
<span style="font-size:18px;"><span style="font-size:18px;">import java.util.*;
public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int length = nums.length;
if (length == 0 || k == 0)
return new int[0];
if (k == 1)
return nums;
int ans[] = new int[length - k + 1];
PriorityQueue<Integer> queue = new PriorityQueue<Integer>(
new neoIntComparator());
for (int i = 0; i < k - 1; i++)
queue.add(nums[i]);
for (int i = k - 1; i < length; i++) {
if (i >= k) {
queue.remove(nums[i - k]);
}
queue.add(nums[i]);
ans[i - k + 1] = queue.peek();
}
return ans;
}
public static void main(String[] args) {
int a[] = new int[] { 1, -1, -1 };
Solution s = new Solution();
int[] ans = s.maxSlidingWindow(a, 2);
for (int i = 0; i < ans.length; i++)
System.out.print(ans[i] + " ");
System.out.println();
}
}
class neoIntComparator implements Comparator<Integer> {
@Override
public int compare(Integer arg0, Integer arg1) {
return arg1 - arg0;
}
}</span></span>
Solution2:
We may still want to figure out a much less time-consuming method, because a a priority queue is still a little bit complex. So here comes another solution.
1. We can store all the data into a stack-like data structure, with the attribute that lower/earlier one has a bigger value. So every time we face with a new number, we need to maintain this attribute: poll the stack until the uppermost one is bigger or equal to this number, then push this number to the top of this stack.
2. Check if the lowest one in the stack is out of the range of the window. This requires we make an if-statement.
3. The current lowest one in the stack is what we want in the current window which ends in nums[i].
Tip: for this sentence --- "the uppermost one is bigger or equal to this number", why equal is also OK here? Because in order to get rid of the case that the lowest number is out of the window range, we simply use one if-statement to check. So in case there are multiple numbers with different positions but same value, and we only keep the earliest one, if it is out of range and we may eliminate it which is absolutely not we want. So we may as well keep all the numbers with same value but different positions.
java
<span style="font-size:18px;">import java.util.*;
import java.util.function.Function;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int length = nums.length;
if (length == 0 || k == 0)
return new int[0];
if (k == 1)
return nums;
int ans[] = new int[length - k + 1];
LinkedList<Integer> dualLinkedList = new LinkedList<Integer>();
for (int i = 0; i < k - 1; i++)
keepTheDualLinkedList(dualLinkedList, nums[i]);
// System.out.println("original one");
// print(dualLinkedList);
for (int i = k - 1; i < length; i++) {
keepTheDualLinkedList(dualLinkedList, nums[i]);
if (i >= k && dualLinkedList.getLast() == nums[i - k])
dualLinkedList.removeLast();
ans[i - k + 1] = dualLinkedList.getLast();
// System.out.println(i + "th step");
// print(dualLinkedList);
}
return ans;
}
void print(LinkedList<Integer> list) {
for (Iterator<Integer> ite = list.iterator(); ite.hasNext();) {
int temp = ite.next();
System.out.printf("%3d", temp);
}
System.out.println();
System.out.println();
}
void keepTheDualLinkedList(LinkedList<Integer> dualList, int num) {
int temp;
while (!dualList.isEmpty()) {
temp = dualList.peek();
if (temp >= num)
break;
dualList.poll();
}
dualList.addFirst(num);
}
public static void main(String[] args) {
int a[] = new int[] { 7, 2, 4 };
Solution s = new Solution();
int[] ans = s.maxSlidingWindow(a, 2);
for (int i = 0; i < ans.length; i++)
System.out.print(ans[i] + " ");
System.out.println();
}
}
</span>
python
<span style="font-size:18px;">class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
length = len(nums)
if (length==0 or k==0):
return []
if (k==1):
return nums
dualLinkedList = []
ans = []
for i in range(0,k-1):
self.keepInStack(dualLinkedList, nums[i])
for i in range(k-1, length):
self.keepInStack(dualLinkedList, nums[i])
if (i>=k and dualLinkedList[0]==nums[i-k]):
dualLinkedList.remove(nums[i-k])
ans.append(dualLinkedList[0])
return ans
def keepInStack(self, linkedList, num):
while (len(linkedList)>0):
topNum = linkedList.pop()
if (topNum>=num):
linkedList.append(topNum)
break;
linkedList.append(num)
</span>