Minimize length of subarray with K (even, odd) pairs
Last Updated :
30 Sep, 2021
Given an array arr[] of N positive integers and an integer K, the task is to find the minimum length of subarray such that there exist at least K pairs of even and odd element provided that even element occurs before odd element. If there doesn’t exist any such subarray, then print “-1”.
Examples:
Input: K = 2, A[] = {1, 2, 3, 4, 5}
Output: 4
Explanation:
The subarray {2, 3, 4, 5} is of length 4, which is minimum. It has at least K(= 2) pairs as {2, 3}, {2, 5} and {4, 5}.
Input: K = 3, A[] = {2, 3, 4, 1, 2, 3}
Output: 4
Explanation: The subarray {2, 3, 4, 1} is of length 4, which is minimum. It has at least K(= 3) pairs as {2, 3}, {2, 1} and {4, 1}.
Naive Approach: The simplest approach to solve the given problem is to generate all possible subarrays of the given array and find the count of pairs satisfying the given criteria in each subarray. After checking for all the subarrays, print the minimum length of that subarray having at least K pairs of even and odd elements such that even element occurs before odd element.
Time Complexity: O(N4)
Auxiliary Space: O(1)
Efficient Approach: The given problem can be solved by using the Two Pointer Technique. Consider an array A[] of size N then,
- Consider two pointers p1 and p2, initialize p1 as 0 and p2 as -1, these two pointers will represent the current window size.
- Let, there are two variables num_pairs (stores the number of valid pairs) and final_ans (stores the length of the minimum possible subarray with at least K valid pairs and it is initialized with INT_MAX).
- Follow the below steps until p2 goes out of range i.e until p2<N:
- Fix p1 at the same position and keep increasing p2 and keep on adding the new valid pairs generated while increasing p2. Continue this process, until the number of valid pairs is less than K. Once num_pairs becomes at least K, update the final_ans and stop.
- Now, start increasing p1 and fix p2 at the same position (where it was after the above step). While increasing p1, keep subtracting the valid pairs which were the result of the inclusion of the element A[p1], and then increment p1. This process continues until the count of valid pairs is greater than or equal to K. While doing this process, keep track of the minimum length subarray (fin_ans) as p1 and p2 are changing.
- Return the final_ans.
Counting number of valid pairs in the range {p1, p2}:
- Maintain a cumulative count array evens[N] and odd[N] for the number of even and odd elements till index i, A[0, i]
- Now, whenever pointer p2 is increased, we add the number of valid pairs generated by including the element A[p2] to the num_pairs.There are two cases:
Case 1: When A[p2] is even, then by considering this element into the existing subarray (A[p1, p2-1]), there won’t be any increase in the number of valid pairs.
Case 2: When A[p2] is odd, then by considering this element into the existing subarray (A[p1, p2-1]), those number of valid pairs will be generated which are equal to the number of even numbers within the range {p1, p2-1}. Since every even number in that range forms a new pair with this newly added odd element, this can be directly calculated using the array evens[N].
- Now, while increasing the pointer p1, subtract those number of valid pairs from num_pairs which were generated by the inclusion of the element A[p1].
There are two cases:
Case 1: When A[p1] is odd, then by removing this element from the existing subarray (A[p1, p2]), there won’t be any decrease in the number of valid pairs.
Case 2: When A[p1] is even, then by removing this element from the existing subarray (A[p1, p2]), those number of valid pairs should be removed which is equal to the number of odd numbers within the range {p1+1, p2}. Since every odd number in the range A{p+1, p2} would have formed a pair with the even number A[p1], this can be directly calculated using the array odds[N].
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int CalculateMinimumSubarray( int A[], int N, int K)
{
vector< int > evens(N, 0), odds(N, 0);
if (A[0] % 2 == 0)
evens[0] = 1;
else
odds[0] = 1;
for ( int i = 1; i < N; i++) {
evens[i] += evens[i - 1] + (A[i] % 2 == 0);
odds[i] += odds[i - 1] + (A[i] % 2 == 1);
}
int final_ans = INT_MAX;
int p1 = 0, p2 = -1;
int num_pairs = 0;
while (p2 < N) {
while (p2 < N && num_pairs < K) {
p2++;
if (p2 >= N) {
break ;
}
if (A[p2] % 2 == 0) {
continue ;
}
int no_evens;
if (p1 == 0) {
no_evens = evens[p2];
}
else {
no_evens = evens[p2] - evens[p1 - 1];
}
num_pairs = num_pairs + no_evens;
if (num_pairs >= K) {
final_ans = min(final_ans, p2 - p1 + 1);
}
}
if (p2 >= N) {
break ;
}
while (num_pairs >= K && p1 < p2) {
if (num_pairs >= K) {
final_ans = min(final_ans, p2 - p1 + 1);
}
if (A[p1] % 2 != 0) {
p1++;
continue ;
}
int no_odds;
if (p1 == 0) {
no_odds = odds[p2];
}
else {
no_odds = odds[p2] - odds[p1 - 1];
}
num_pairs = num_pairs - no_odds;
p1++;
}
}
if (final_ans != INT_MAX) {
return final_ans;
}
return -1;
}
int main()
{
int N = 5;
int K = 2;
int A[5] = { 1, 2, 3, 4, 5 };
cout << CalculateMinimumSubarray(A, N, K) << endl;
}
|
Java
import java.util.Arrays;
class GFG {
public static int CalculateMinimumSubarray( int A[], int N, int K)
{
int [] evens = new int [N];
int [] odds = new int [N];
Arrays.fill(evens, 0 );
Arrays.fill(odds, 0 );
if (A[ 0 ] % 2 == 0 )
evens[ 0 ] = 1 ;
else
odds[ 0 ] = 1 ;
for ( int i = 1 ; i < N; i++) {
evens[i] += evens[i - 1 ] + ((A[i] % 2 == 0 ) ? 1 : 0 );
odds[i] += odds[i - 1 ] + ((A[i] % 2 == 1 ) ? 1 : 0 );
}
int final_ans = Integer.MAX_VALUE;
int p1 = 0 , p2 = - 1 ;
int num_pairs = 0 ;
while (p2 < N) {
while (p2 < N && num_pairs < K) {
p2++;
if (p2 >= N) {
break ;
}
if (A[p2] % 2 == 0 ) {
continue ;
}
int no_evens;
if (p1 == 0 ) {
no_evens = evens[p2];
} else {
no_evens = evens[p2] - evens[p1 - 1 ];
}
num_pairs = num_pairs + no_evens;
if (num_pairs >= K) {
final_ans = Math.min(final_ans, p2 - p1 + 1 );
}
}
if (p2 >= N) {
break ;
}
while (num_pairs >= K && p1 < p2) {
if (num_pairs >= K) {
final_ans = Integer.min(final_ans, p2 - p1 + 1 );
}
if (A[p1] % 2 != 0 ) {
p1++;
continue ;
}
int no_odds;
if (p1 == 0 ) {
no_odds = odds[p2];
} else {
no_odds = odds[p2] - odds[p1 - 1 ];
}
num_pairs = num_pairs - no_odds;
p1++;
}
}
if (final_ans != Integer.MAX_VALUE) {
return final_ans;
}
return - 1 ;
}
public static void main(String args[]) {
int N = 5 ;
int K = 2 ;
int A[] = { 1 , 2 , 3 , 4 , 5 };
System.out.println(CalculateMinimumSubarray(A, N, K));
}
}
|
Python3
import sys
def CalculateMinimumSubarray(A, N, K):
evens = [ 0 for i in range (N)]
odds = [ 0 for i in range (N)]
if (A[ 0 ] % 2 = = 0 ):
evens[ 0 ] = 1
else :
odds[ 0 ] = 1
for i in range ( 1 ,N, 1 ):
evens[i] + = evens[i - 1 ] + (A[i] % 2 = = 0 )
odds[i] + = odds[i - 1 ] + (A[i] % 2 = = 1 )
final_ans = sys.maxsize
p1 = 0
p2 = - 1
num_pairs = 0
while (p2 < N):
while (p2 < N and num_pairs < K):
p2 + = 1
if (p2 > = N):
break
if (A[p2] % 2 = = 0 ):
continue
no_evens = 0
if (p1 = = 0 ):
no_evens = evens[p2]
else :
no_evens = evens[p2] - evens[p1 - 1 ]
num_pairs = num_pairs + no_evens
if (num_pairs > = K):
final_ans = min (final_ans, p2 - p1 + 1 )
if (p2 > = N):
break
while (num_pairs > = K and p1 < p2):
if (num_pairs > = K):
final_ans = min (final_ans, p2 - p1 + 1 )
if (A[p1] % 2 ! = 0 ):
p1 + = 1
continue
no_odds = 0
if (p1 = = 0 ):
no_odds = odds[p2]
else :
no_odds = odds[p2] - odds[p1 - 1 ]
num_pairs = num_pairs - no_odds
p1 + = 1
if (final_ans ! = sys.maxsize):
return final_ans
return - 1
if __name__ = = '__main__' :
N = 5
K = 2
A = [ 1 , 2 , 3 , 4 , 5 ]
print (CalculateMinimumSubarray(A, N, K))
|
C#
using System;
public class GFG{
public static int CalculateMinimumSubarray( int [] A, int N, int K)
{
int [] evens = new int [N];
int [] odds = new int [N];
Array.Fill(evens, 0);
Array.Fill(odds, 0);
if (A[0] % 2 == 0)
evens[0] = 1;
else
odds[0] = 1;
for ( int i = 1; i < N; i++) {
evens[i] += evens[i - 1] + ((A[i] % 2 == 0) ? 1 : 0);
odds[i] += odds[i - 1] + ((A[i] % 2 == 1) ? 1 : 0);
}
int final_ans = Int32.MaxValue;
int p1 = 0, p2 = -1;
int num_pairs = 0;
while (p2 < N) {
while (p2 < N && num_pairs < K) {
p2++;
if (p2 >= N) {
break ;
}
if (A[p2] % 2 == 0) {
continue ;
}
int no_evens;
if (p1 == 0) {
no_evens = evens[p2];
} else {
no_evens = evens[p2] - evens[p1 - 1];
}
num_pairs = num_pairs + no_evens;
if (num_pairs >= K) {
final_ans = Math.Min(final_ans, p2 - p1 + 1);
}
}
if (p2 >= N) {
break ;
}
while (num_pairs >= K && p1 < p2) {
if (num_pairs >= K) {
final_ans = Math.Min(final_ans, p2 - p1 + 1);
}
if (A[p1] % 2 != 0) {
p1++;
continue ;
}
int no_odds;
if (p1 == 0) {
no_odds = odds[p2];
} else {
no_odds = odds[p2] - odds[p1 - 1];
}
num_pairs = num_pairs - no_odds;
p1++;
}
}
if (final_ans != Int32.MaxValue) {
return final_ans;
}
return -1;
}
static public void Main (){
int N = 5;
int K = 2;
int [] A = { 1, 2, 3, 4, 5 };
Console.WriteLine(CalculateMinimumSubarray(A, N, K));
}
}
|
Javascript
<script>
function CalculateMinimumSubarray(A, N, K)
{
let evens = new Array(N).fill(0);
let odds = new Array(N).fill(0)
if (A[0] % 2 == 0)
evens[0] = 1;
else
odds[0] = 1;
for (let i = 1; i < N; i++) {
evens[i] += evens[i - 1] + (A[i] % 2 == 0);
odds[i] += odds[i - 1] + (A[i] % 2 == 1);
}
let final_ans = Number.MAX_VALUE;
let p1 = 0, p2 = -1;
let num_pairs = 0;
while (p2 < N) {
while (p2 < N && num_pairs < K) {
p2++;
if (p2 >= N) {
break ;
}
if (A[p2] % 2 == 0) {
continue ;
}
let no_evens;
if (p1 == 0) {
no_evens = evens[p2];
}
else {
no_evens = evens[p2] - evens[p1 - 1];
}
num_pairs = num_pairs + no_evens;
if (num_pairs >= K) {
final_ans = Math.min(final_ans, p2 - p1 + 1);
}
}
if (p2 >= N) {
break ;
}
while (num_pairs >= K && p1 < p2) {
if (num_pairs >= K) {
final_ans = Math.min(final_ans, p2 - p1 + 1);
}
if (A[p1] % 2 != 0) {
p1++;
continue ;
}
let no_odds;
if (p1 == 0) {
no_odds = odds[p2];
}
else {
no_odds = odds[p2] - odds[p1 - 1];
}
num_pairs = num_pairs - no_odds;
p1++;
}
}
if (final_ans != Number.MAX_VALUE) {
return final_ans;
}
return -1;
}
let N = 5;
let K = 2;
let A = [1, 2, 3, 4, 5];
document.write(CalculateMinimumSubarray(A, N, K));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...