To solve the problem of finding the first negative number in every window of size k
in an array, we can use a sliding window approach. I’ll explain the brute force, better, and optimal approaches in C++, providing code along with a dry run for each.
Problem Statement:
Given an array arr[]
and an integer k
, find the first negative number in every window of size k
. If there is no negative number in the window, print 0
.
1. Brute Force Approach
In the brute force approach, we will loop through each window of size k
and find the first negative number. This approach has a time complexity of O(n * k) because for each window of size k
, we are scanning through the elements.
Code:
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
void firstNegativeNumberBruteForce(vector<int>& arr, int k) {
int n = arr.size();
for (int i = 0; i <= n - k; i++) {
bool found = false;
for (int j = i; j < i + k; j++) {
if (arr[j] < 0) {
cout << arr[j] << " ";
found = true;
break; // exit as soon as we find the first negative number
}
}
if (!found) {
cout << "0 "; // No negative number in the window
}
}
cout << endl;
}
int main() {
vector<int> arr = {12, -1, -7, 8, -15, 30, 16, 28};
int k = 3;
firstNegativeNumberBruteForce(arr, k);
return 0;
}
Explanation:
- We iterate through each window of size
k
. - For each window, we look for the first negative number.
- If no negative number is found, we print
0
.
Dry Run:
For arr = [12, -1, -7, 8, -15, 30, 16, 28]
and k = 3
:
- Window 1: [12, -1, -7] → The first negative number is
-1
. Print-1
. - Window 2: [-1, -7, 8] → The first negative number is
-1
. Print-1
. - Window 3: [-7, 8, -15] → The first negative number is
-7
. Print-7
. - Window 4: [8, -15, 30] → The first negative number is
-15
. Print-15
. - Window 5: [-15, 30, 16] → The first negative number is
-15
. Print-15
. - Window 6: [30, 16, 28] → No negative number, so print
0
.
Output:
-1 -1 -7 -15 -15 0
Time Complexity:
- O(n * k) where
n
is the length of the array, andk
is the window size.
2. Better Approach (Using a Queue)
In the better approach, we can optimize the brute force solution by using a queue to store the indices of negative numbers. This reduces the time complexity to O(n), as we are iterating through the array only once.
Explanation of Better Approach:
- We maintain a deque (
dq
) to store indices of negative numbers. - For each new window, we:
- Remove elements from the front of the deque that are out of the current window.
- Add the current negative number to the deque.
- Output the first negative number in the deque or
0
if there are no negative numbers.
class Solution {
public:
vector<int> FirstNegativeInteger(vector<int>& arr, int k) {
// write code here
deque<int>dq;
vector<int>ans;
int n = arr.size();
// Process the first window
for(int i = 0; i < k; i++) {
if(arr[i] < 0) dq.push_back(i);
}
// Add the result for the first window
if(!dq.empty()) ans.push_back(arr[dq.front()]);
else ans.push_back(0);
// Process the remaining windows
for(int i = k; i < n; i++) {
// Remove elements that are out of the current window
while(!dq.empty() && dq.front() <= i - k) dq.pop_front();
// Add the current element to the deque if it's negative
if(arr[i] < 0) dq.push_back(i);
// Add the result for the current window
if(!dq.empty()) ans.push_back(arr[dq.front()]);
else ans.push_back(0);
}
return ans;
}
};
Dry Run Step-by-Step:
- Initialize the deque to store indices of negative numbers in the window.
- Process the first window (first
k
elements) separately:- The first window contains the elements
[12, -1, -7]
(i.e., indices 0 to 2). - We iterate through the window and find the negative numbers.
- The first window contains the elements
- Start processing the rest of the array from index
k
ton-1
.- For each new window, we:
- Print the first negative number from the deque.
- Remove indices that are out of the window.
- Add the current negative number (if any) to the deque.
- For each new window, we:
Dry Run for
arr = [12, -1, -7, 8, -15, 30, 16, 28]
and k = 3
:
- First Window: Indices 0 to 2 (
[12, -1, -7]
)- For indices 0 to 2, we check the negative numbers:
arr[0] = 12
→ not negative.arr[1] = -1
→ negative, so add index1
to the deque.arr[2] = -7
→ negative, so add index2
to the deque.
- Now, the deque contains indices
[1, 2]
, pointing to-1
and-7
. - First negative number:
-1
(because index1
is the first in the deque). - Output so far:
-1
- For indices 0 to 2, we check the negative numbers:
- Window 2: Indices 1 to 3 (
[-1, -7, 8]
)- Remove indices that are out of the window:
1
is still in the window, so we don’t remove it.2
is still in the window, so we don’t remove it.
- Add the new element
arr[3] = 8
, which is not negative. - The deque still contains indices
[1, 2]
. - First negative number:
-1
(because index1
is still the first in the deque). - Output so far:
-1 -1
- Remove indices that are out of the window:
- Window 3: Indices 2 to 4 (
[-7, 8, -15]
)- Remove indices that are out of the window:
- Index
1
is out of the window, so we remove it.
- Index
- The deque now contains
[2]
(pointing to-7
). - Add the new element
arr[4] = -15
, which is negative, so we add index4
to the deque. - The deque now contains
[2, 4]
. - First negative number:
-7
(because index2
is still the first in the deque). - Output so far:
-1 -1 -7
- Remove indices that are out of the window:
- Window 4: Indices 3 to 5 (
[8, -15, 30]
)- Remove indices that are out of the window:
- Index
2
is out of the window, so we remove it.
- Index
- The deque now contains
[4]
(pointing to-15
). - Add the new element
arr[5] = 30
, which is not negative. - The deque still contains
[4]
. - First negative number:
-15
(because index4
is still the first in the deque). - Output so far:
-1 -1 -7 -15
- Remove indices that are out of the window:
- Window 5: Indices 4 to 6 (
[-15, 30, 16]
)- Remove indices that are out of the window:
- Index
4
is still in the window.
- Index
- The deque now contains
[4]
(pointing to-15
). - Add the new element
arr[6] = 16
, which is not negative. - The deque still contains
[4]
. - First negative number:
-15
(because index4
is still the first in the deque). - Output so far:
-1 -1 -7 -15 -15
- Remove indices that are out of the window:
- Window 6: Indices 5 to 7 (
[30, 16, 28]
)- Remove indices that are out of the window:
- Index
4
is out of the window, so we remove it.
- Index
- The deque is now empty.
- Add the new element
arr[7] = 28
, which is not negative. - The deque is empty, so no negative number is found.
- First negative number:
0
(since the deque is empty). - Output so far:
-1 -1 -7 -15 -15 0
- Remove indices that are out of the window:
Final Output:
-1 -1 -7 -15 -15 0
Time Complexity:
- O(n), where
n
is the length of the array.

Conclusion:
- Brute Force Approach: O(n * k) — Simply iterate over each window and find the first negative number.
- Better Approach: O(n) — Use a deque to keep track of negative numbers in the window, leading to a much faster solution.