First Negative In Every Window
You have been given an array of integers 'ARR' of size 'N'. You are also provided with a positive integer 'K'.
Your task is to find the first negative element in every window (contiguous subarray) of length 'K'. If there is no negative element in a window, then print 0 for that window.
For example:
For the given array 'ARR' = [5, -3, 2, 3, -4] and 'K' = 2.
Output = -3 -3 0 -4
We have four windows of length 2 in 'ARR'
[5, -3] having -3 as first negative element.
[-3, 2] having -3 as first negative element.
[2, 3] having no negative element
[2, -4] having -4 as first negative element.
Input Format:
The first line of input contains an integer 'T' representing the number of test cases or queries to be processed. Then the test case follows.
The first line of each test case contains two single space-separated integers 'N' and 'K' representing the size of the array/list and the positive integer denoting the length of the window respectively.
The second line of each test case contains 'N' single space-separated integers representing the array/list elements.
Output Format:
For each test case, print (N - K + 1) single space-separated integers representing the first negative element in each of the windows of length 'K'.
Print output of each test case in a separate line.
Note:
You are not required to print the expected output; it has already been taken care of. Just implement the function.
Constraints:
1 <= T <= 10
1 <= N <= 5 * 10^4
1 <= K <= N
-10^9 <= ARR[i] <= 10^9
Time Limit: 1 sec
We have a simple brute force solution for this problem. We will traverse in every subarray of length ‘K’ and find our first negative element for each of them. For this, we will use two nested loops.
The outer loop will give us the starting point for each window of length ‘K’ and the inner loop will traverse in this window to find our first negative element. We will keep updating our answer for each window in another array.
The idea is to use a Queue data structure that follows the First In, First Out strategy and a sliding window of length ‘K’. But how did we come to this conclusion?
If we process every window of length ‘K’ with the help of a sliding window, we can think of this problem as pushing negative elements into a window of length ‘K’ from behind and removing them from the front which is the basic principle of a Queue. Also, before each insertion and deletion, we have to report the front element (first negative) of the window.
The only difference that we have here is that we also have positive integers in our array. So, while we slide our window of length ‘K’ in our array, we only insert negative elements into our Queue. If the Queue is empty at any point, then we don’t have any negative element in our current window.
Here, is the complete algorithm:
- Declare an array ‘ANS’ of size (N - K + 1) i.e. total windows in the array, to store our answer.
- Declare a queue.
- Insert the negative elements of the first window (starting from index 0) into the queue.
- Initialize ‘start’ to 0 and ‘end’ to ‘K’-1. These variables represent the start and end indexes of our sliding window.
- Loop ‘end’ < ‘N’.
- If the queue is empty, update the first negative for the current window as 0 and continue.
- Else
- Initialize ‘currIndex’ to the front element of Queue.
- Update the first negative element for this window as ARR[currIndex].
- If ‘start’ == ‘currIndex’, then this element will not be present in further windows, so pop it from the Queue.
- Increment ‘start’ and ‘end’ by 1.
- Insert ARR[end] into the Queue, if ARR[end] is negative.
- Return ‘ANS’.
The idea here is to use Two pointers, one for the ‘end’ of the window and one for the ‘index’ of the first negative element inside the window.
Here, is the complete algorithm:
- Declare an array ‘ANS’ of size (N - K + 1) i.e. total windows in the array, to store our answer.
- Initialize ‘firstNegIndex’ to 0 and ‘end’ to K-1.
- Loop till ‘end’ < N
- Increment ‘firstNegIndex’ by 1 until we find a negative element or we are out of the window.
- If there is no negative element in the window. Update 0 in ‘ANS’.
- Else, Update ARR[firstNegIndex] in ‘ANS’ for the current window.
- Return ‘ANS’.