Open In App

Minimize length of subarray with K (even, odd) pairs

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,

Counting number of valid pairs in the range {p1, p2}:

Below is the implementation of the above approach:




#include <bits/stdc++.h>
using namespace std;
  
// Function to calculate the length of the
// smallest possible sub array with at least K
// valid pairs.
int CalculateMinimumSubarray(int A[], int N, int K)
{
    // Vector to store the cumulative count of the number
    // of even numbers and odd numbers.
    // For every i, evens[i] and odds[i] represents
    // the number of evens and odd elements
    // encountered till index 'i'
    vector<int> evens(N, 0), odds(N, 0);
  
    if (A[0] % 2 == 0)
        evens[0] = 1;
    else
        odds[0] = 1;
  
    // Calculating the cumulative even and
    // odd vectors
    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);
    }
  
    // Store the minimum length subarray with
    // atleast K valid pairs
    int final_ans = INT_MAX;
  
    // Initializing two pointers.
    int p1 = 0, p2 = -1;
  
    // Stores the number of valid pairs in
    // the range {p1, p2}
    int num_pairs = 0;
  
    // Incrementing p2
    while (p2 < N) {
  
        // Incrementing pointer p2 until there
        // are atleast K valid pairs
        // between the range {p1, p2}.
        while (p2 < N && num_pairs < K) {
            p2++;
  
            // If p2 >= N, stop.
            if (p2 >= N) {
                break;
            }
  
            // If A[p2] is an even number, then
            // the number of valid pairs won't
            // increase, so just continue.
            if (A[p2] % 2 == 0) {
                continue;
            }
  
            // If A[p2] is an odd number, then those many
            // number of valid pairs will be generated which
            // which are equal to the number of even numbers
            // within the range {p1, p2-1}. Since every even
            // number forms a new pair with this odd element.
            int no_evens;
            if (p1 == 0) {
                no_evens = evens[p2];
            }
            else {
                no_evens = evens[p2] - evens[p1 - 1];
            }
  
            // Increment the num_pairs variable with
            // the number of even numbers in the range
            // {p1, p2-1} as calculated above.
            num_pairs = num_pairs + no_evens;
  
            // Update final_ans
            if (num_pairs >= K) {
                final_ans = min(final_ans, p2 - p1 + 1);
            }
        }
        if (p2 >= N) {
            break;
        }
  
        // Increment the pointer p1 until
        // num_pairs >= K.
        while (num_pairs >= K && p1 < p2) {
  
            // Update final_ans
            if (num_pairs >= K) {
                final_ans = min(final_ans, p2 - p1 + 1);
            }
  
            // If A[p1] is an odd number, then removing that
            // element won't decrease the num_pairs.
            if (A[p1] % 2 != 0) {
                p1++;
                continue;
            }
  
            // If A[p1] is an even number, then we should
            // subtract those number of valid pairs from
            // num_pairs which is equal to the number of odd
            // numbers in the range {p1+1, p2}. Since every
            // odd number in the range {p1+1, p2} would have
            // formed a pair with the even number at A[p1]
            int no_odds;
            if (p1 == 0) {
                no_odds = odds[p2];
            }
            else {
                no_odds = odds[p2] - odds[p1 - 1];
            }
            // now we decrease the num_pairs with the value
            // calculated above, that is number of odd
            // numbers from A[p1+1, p2]
            num_pairs = num_pairs - no_odds;
            p1++;
        }
    }
  
    // If final_ans is updated atleast once,
    // then it means there is atleast one sub-array
    // of some size with atleast K valid pairs.
    // And however we have calculated the subarray
    // of minimum length.
    // So we return its length.
    if (final_ans != INT_MAX) {
        return final_ans;
    }
  
    // If the final_ans is never updated,
    // it means that there is no subarray
    // of any size with atleast K valid
    // pairs. So we return -1.
    return -1;
}
  
// Driver Code
int main()
{
    int N = 5;
    int K = 2;
    int A[5] = { 1, 2, 3, 4, 5 };
  
    cout << CalculateMinimumSubarray(A, N, K) << endl;
}




import java.util.Arrays;
  
class GFG {
  
    // Function to calculate the length of the
    // smallest possible sub array with at least K
    // valid pairs.
    public static int CalculateMinimumSubarray(int A[], int N, int K) 
    {
        
        // Vector to store the cumulative count of the number
        // of even numbers and odd numbers.
        // For every i, evens[i] and odds[i] represents
        // the number of evens and odd elements
        // encountered till index 'i'
        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;
  
        // Calculating the cumulative even and
        // odd vectors
        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);
        }
  
        // Store the minimum length subarray with
        // atleast K valid pairs
        int final_ans = Integer.MAX_VALUE;
  
        // Initializing two pointers.
        int p1 = 0, p2 = -1;
  
        // Stores the number of valid pairs in
        // the range {p1, p2}
        int num_pairs = 0;
  
        // Incrementing p2
        while (p2 < N) {
  
            // Incrementing pointer p2 until there
            // are atleast K valid pairs
            // between the range {p1, p2}.
            while (p2 < N && num_pairs < K) {
                p2++;
  
                // If p2 >= N, stop.
                if (p2 >= N) {
                    break;
                }
  
                // If A[p2] is an even number, then
                // the number of valid pairs won't
                // increase, so just continue.
                if (A[p2] % 2 == 0) {
                    continue;
                }
  
                // If A[p2] is an odd number, then those many
                // number of valid pairs will be generated which
                // which are equal to the number of even numbers
                // within the range {p1, p2-1}. Since every even
                // number forms a new pair with this odd element.
                int no_evens;
                if (p1 == 0) {
                    no_evens = evens[p2];
                } else {
                    no_evens = evens[p2] - evens[p1 - 1];
                }
  
                // Increment the num_pairs variable with
                // the number of even numbers in the range
                // {p1, p2-1} as calculated above.
                num_pairs = num_pairs + no_evens;
  
                // Update final_ans
                if (num_pairs >= K) {
                    final_ans = Math.min(final_ans, p2 - p1 + 1);
                }
            }
            if (p2 >= N) {
                break;
            }
  
            // Increment the pointer p1 until
            // num_pairs >= K.
            while (num_pairs >= K && p1 < p2) {
  
                // Update final_ans
                if (num_pairs >= K) {
                    final_ans = Integer.min(final_ans, p2 - p1 + 1);
                }
  
                // If A[p1] is an odd number, then removing that
                // element won't decrease the num_pairs.
                if (A[p1] % 2 != 0) {
                    p1++;
                    continue;
                }
  
                // If A[p1] is an even number, then we should
                // subtract those number of valid pairs from
                // num_pairs which is equal to the number of odd
                // numbers in the range {p1+1, p2}. Since every
                // odd number in the range {p1+1, p2} would have
                // formed a pair with the even number at A[p1]
                int no_odds;
                if (p1 == 0) {
                    no_odds = odds[p2];
                } else {
                    no_odds = odds[p2] - odds[p1 - 1];
                }
                
                // now we decrease the num_pairs with the value
                // calculated above, that is number of odd
                // numbers from A[p1+1, p2]
                num_pairs = num_pairs - no_odds;
                p1++;
            }
        }
  
        // If final_ans is updated atleast once,
        // then it means there is atleast one sub-array
        // of some size with atleast K valid pairs.
        // And however we have calculated the subarray
        // of minimum length.
        // So we return its length.
        if (final_ans != Integer.MAX_VALUE) {
            return final_ans;
        }
  
        // If the final_ans is never updated,
        // it means that there is no subarray
        // of any size with atleast K valid
        // pairs. So we return -1.
        return -1;
    }
  
    // Driver Code
    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));
    }
}
  
// This code is contributed by saurabh_jaiswal.




import sys
  
# Function to calculate the length of the
# smallest possible sub array with at least K
# valid pairs.
def CalculateMinimumSubarray(A, N, K):
    
    # Vector to store the cumulative count of the number
    # of even numbers and odd numbers.
    # For every i, evens[i] and odds[i] represents
    # the number of evens and odd elements
    # encountered till index 'i'
    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
  
    # Calculating the cumulative even and
    # odd vectors
    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)
  
    # Store the minimum length subarray with
    # atleast K valid pairs
    final_ans = sys.maxsize
  
    # Initializing two pointers.
    p1 = 0
    p2 = -1
  
    # Stores the number of valid pairs in
    # the range {p1, p2}
    num_pairs = 0
  
    # Incrementing p2
    while (p2 < N):
  
        # Incrementing pointer p2 until there
        # are atleast K valid pairs
        # between the range {p1, p2}.
        while (p2 < N and num_pairs < K):
            p2 += 1
  
            # If p2 >= N, stop.
            if (p2 >= N):
                break
  
            # If A[p2] is an even number, then
            # the number of valid pairs won't
            # increase, so just continue.
            if (A[p2] % 2 == 0):
                continue
  
            # If A[p2] is an odd number, then those many
            # number of valid pairs will be generated which
            # which are equal to the number of even numbers
            # within the range {p1, p2-1}. Since every even
            # number forms a new pair with this odd element.
            no_evens = 0
            if (p1 == 0):
                no_evens = evens[p2]
            else:
                no_evens = evens[p2] - evens[p1 - 1]
  
            # Increment the num_pairs variable with
            # the number of even numbers in the range
            # {p1, p2-1} as calculated above.
            num_pairs = num_pairs + no_evens
  
            # Update final_ans
            if (num_pairs >= K):
                final_ans = min(final_ans, p2 - p1 + 1)
        if (p2 >= N):
            break
  
        # Increment the pointer p1 until
        # num_pairs >= K.
        while (num_pairs >= K and p1 < p2):
  
            # Update final_ans
            if (num_pairs >= K):
                final_ans = min(final_ans, p2 - p1 + 1)
  
            # If A[p1] is an odd number, then removing that
            # element won't decrease the num_pairs.
            if (A[p1] % 2 != 0):
                p1 += 1
                continue
  
            # If A[p1] is an even number, then we should
            # subtract those number of valid pairs from
            # num_pairs which is equal to the number of odd
            # numbers in the range {p1+1, p2}. Since every
            # odd number in the range {p1+1, p2} would have
            # formed a pair with the even number at A[p1]
            no_odds = 0
            if (p1 == 0):
                no_odds = odds[p2]
            else:
                no_odds = odds[p2] - odds[p1 - 1]
            # now we decrease the num_pairs with the value
            # calculated above, that is number of odd
            # numbers from A[p1+1, p2]
            num_pairs = num_pairs - no_odds
            p1 += 1
  
    # If final_ans is updated atleast once,
    # then it means there is atleast one sub-array
    # of some size with atleast K valid pairs.
    # And however we have calculated the subarray
    # of minimum length.
    # So we return its length.
    if (final_ans != sys.maxsize):
        return final_ans
  
    # If the final_ans is never updated,
    # it means that there is no subarray
    # of any size with atleast K valid
    # pairs. So we return -1.
    return -1
  
# Driver Code
if __name__ == '__main__':
    N = 5
    K = 2
    A = [1, 2, 3, 4, 5]
  
    print(CalculateMinimumSubarray(A, N, K))
      
    # This code is contributed by SURENDRA_GANGWAR.




using System;
  
public class GFG{
          
      // Function to calculate the length of the
    // smallest possible sub array with at least K
    // valid pairs.
    public static int CalculateMinimumSubarray(int[] A, int N, int K) 
    {
        
        // Vector to store the cumulative count of the number
        // of even numbers and odd numbers.
        // For every i, evens[i] and odds[i] represents
        // the number of evens and odd elements
        // encountered till index 'i'
        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;
  
        // Calculating the cumulative even and
        // odd vectors
        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);
        }
  
        // Store the minimum length subarray with
        // atleast K valid pairs
        int final_ans = Int32.MaxValue;
  
        // Initializing two pointers.
        int p1 = 0, p2 = -1;
  
        // Stores the number of valid pairs in
        // the range {p1, p2}
        int num_pairs = 0;
  
        // Incrementing p2
        while (p2 < N) {
  
            // Incrementing pointer p2 until there
            // are atleast K valid pairs
            // between the range {p1, p2}.
            while (p2 < N && num_pairs < K) {
                p2++;
  
                // If p2 >= N, stop.
                if (p2 >= N) {
                    break;
                }
  
                // If A[p2] is an even number, then
                // the number of valid pairs won't
                // increase, so just continue.
                if (A[p2] % 2 == 0) {
                    continue;
                }
  
                // If A[p2] is an odd number, then those many
                // number of valid pairs will be generated which
                // which are equal to the number of even numbers
                // within the range {p1, p2-1}. Since every even
                // number forms a new pair with this odd element.
                int no_evens;
                if (p1 == 0) {
                    no_evens = evens[p2];
                } else {
                    no_evens = evens[p2] - evens[p1 - 1];
                }
  
                // Increment the num_pairs variable with
                // the number of even numbers in the range
                // {p1, p2-1} as calculated above.
                num_pairs = num_pairs + no_evens;
  
                // Update final_ans
                if (num_pairs >= K) {
                    final_ans = Math.Min(final_ans, p2 - p1 + 1);
                }
            }
            if (p2 >= N) {
                break;
            }
  
            // Increment the pointer p1 until
            // num_pairs >= K.
            while (num_pairs >= K && p1 < p2) {
  
                // Update final_ans
                if (num_pairs >= K) {
                    final_ans = Math.Min(final_ans, p2 - p1 + 1);
                }
  
                // If A[p1] is an odd number, then removing that
                // element won't decrease the num_pairs.
                if (A[p1] % 2 != 0) {
                    p1++;
                    continue;
                }
  
                // If A[p1] is an even number, then we should
                // subtract those number of valid pairs from
                // num_pairs which is equal to the number of odd
                // numbers in the range {p1+1, p2}. Since every
                // odd number in the range {p1+1, p2} would have
                // formed a pair with the even number at A[p1]
                int no_odds;
                if (p1 == 0) {
                    no_odds = odds[p2];
                } else {
                    no_odds = odds[p2] - odds[p1 - 1];
                }
                
                // now we decrease the num_pairs with the value
                // calculated above, that is number of odd
                // numbers from A[p1+1, p2]
                num_pairs = num_pairs - no_odds;
                p1++;
            }
        }
  
        // If final_ans is updated atleast once,
        // then it means there is atleast one sub-array
        // of some size with atleast K valid pairs.
        // And however we have calculated the subarray
        // of minimum length.
        // So we return its length.
        if (final_ans != Int32.MaxValue) {
            return final_ans;
        }
  
        // If the final_ans is never updated,
        // it means that there is no subarray
        // of any size with atleast K valid
        // pairs. So we return -1.
        return -1;
    }
  
    // Driver Code
    static public void Main (){
  
        int N = 5;
        int K = 2;
        int[] A = { 1, 2, 3, 4, 5 };
  
        Console.WriteLine(CalculateMinimumSubarray(A, N, K));
    }
}
  
// This code is contributed by Dharanendra L V.




<script>
        // JavaScript Program to implement
        // the above approach
  
        // Function to calculate the length of the
        // smallest possible sub array with at least K
        // valid pairs.
        function CalculateMinimumSubarray(A, N, K) 
        {
          
            // Vector to store the cumulative count of the number
            // of even numbers and odd numbers.
            // For every i, evens[i] and odds[i] represents
            // the number of evens and odd elements
            // encountered till index 'i'
            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;
  
            // Calculating the cumulative even and
            // odd vectors
            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);
            }
  
            // Store the minimum length subarray with
            // atleast K valid pairs
            let final_ans = Number.MAX_VALUE;
  
            // Initializing two pointers.
            let p1 = 0, p2 = -1;
  
            // Stores the number of valid pairs in
            // the range {p1, p2}
            let num_pairs = 0;
  
            // Incrementing p2
            while (p2 < N) {
  
                // Incrementing pointer p2 until there
                // are atleast K valid pairs
                // between the range {p1, p2}.
                while (p2 < N && num_pairs < K) {
                    p2++;
  
                    // If p2 >= N, stop.
                    if (p2 >= N) {
                        break;
                    }
  
                    // If A[p2] is an even number, then
                    // the number of valid pairs won't
                    // increase, so just continue.
                    if (A[p2] % 2 == 0) {
                        continue;
                    }
  
                    // If A[p2] is an odd number, then those many
                    // number of valid pairs will be generated which
                    // which are equal to the number of even numbers
                    // within the range {p1, p2-1}. Since every even
                    // number forms a new pair with this odd element.
                    let no_evens;
                    if (p1 == 0) {
                        no_evens = evens[p2];
                    }
                    else {
                        no_evens = evens[p2] - evens[p1 - 1];
                    }
  
                    // Increment the num_pairs variable with
                    // the number of even numbers in the range
                    // {p1, p2-1} as calculated above.
                    num_pairs = num_pairs + no_evens;
  
                    // Update final_ans
                    if (num_pairs >= K) {
                        final_ans = Math.min(final_ans, p2 - p1 + 1);
                    }
                }
                if (p2 >= N) {
                    break;
                }
  
                // Increment the pointer p1 until
                // num_pairs >= K.
                while (num_pairs >= K && p1 < p2) {
  
                    // Update final_ans
                    if (num_pairs >= K) {
                        final_ans = Math.min(final_ans, p2 - p1 + 1);
                    }
  
                    // If A[p1] is an odd number, then removing that
                    // element won't decrease the num_pairs.
                    if (A[p1] % 2 != 0) {
                        p1++;
                        continue;
                    }
  
                    // If A[p1] is an even number, then we should
                    // subtract those number of valid pairs from
                    // num_pairs which is equal to the number of odd
                    // numbers in the range {p1+1, p2}. Since every
                    // odd number in the range {p1+1, p2} would have
                    // formed a pair with the even number at A[p1]
                    let no_odds;
                    if (p1 == 0) {
                        no_odds = odds[p2];
                    }
                    else {
                        no_odds = odds[p2] - odds[p1 - 1];
                    }
                      
                    // now we decrease the num_pairs with the value
                    // calculated above, that is number of odd
                    // numbers from A[p1+1, p2]
                    num_pairs = num_pairs - no_odds;
                    p1++;
                }
            }
  
            // If final_ans is updated atleast once,
            // then it means there is atleast one sub-array
            // of some size with atleast K valid pairs.
            // And however we have calculated the subarray
            // of minimum length.
            // So we return its length.
            if (final_ans != Number.MAX_VALUE) {
                return final_ans;
            }
  
            // If the final_ans is never updated,
            // it means that there is no subarray
            // of any size with atleast K valid
            // pairs. So we return -1.
            return -1;
        }
  
        // Driver Code
        let N = 5;
        let K = 2;
        let A = [1, 2, 3, 4, 5];
  
        document.write(CalculateMinimumSubarray(A, N, K));
  
     // This code is contributed by Potta Lokesh
    </script>

Output
4

Time Complexity: O(N)
Auxiliary Space: O(N)


Article Tags :