Open In App

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

Last Updated : 30 Sep, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

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;
  
// 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;
}


Java




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.


Python3




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.


C#




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.


Javascript




<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)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads