Find minimum length sub-array which has given sub-sequence in it

Given an array arr[] of N elements, the task is to find the length of the smallest sub-array which has sequence {0, 1, 2, 3, 4} as a sub-sequence in it.

Examples:

Input: arr[] = {0, 1, 2, 3, 4, 2, 0, 3, 4}
Output: 5
Required Subarray is {0, 1, 2, 3, 4} with minimum length.
The entire array also contains the sequence
but it is not minimum in length.



Input: arr[] = {0, 1, 1, 0, 1, 2, 0, 3, 4}
Output: 6

Approach:

  • Maintain an array pref[] of size 5 (equal to size of the sequence) where pref[i] stores the count of i in the given array till now.
  • We can increase the count of pref for any number only if pref[Array[i] – 1] > 0, this is because in order to have the complete sequence as a sub-sequence of the array all the previous elements of the sequence must occur before the current. Also, store the indices of these elements found so far.
  • Whenever we witness 4 i.e. the possible end of the sub-sequence and pref[3] > 0 implies that we have found the sequence in our array. Now mark that index as end as well as start point and for all other numbers in sequence from 3 to 0. Apply binary search to find their most closest index to the next element of the sequence which will get us the size of the current valid sub-array.
  • Answer is the minimum size of all the valid sub-arrays found in the previous step.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
#define MAX_INT 1000000
  
// Function to return the minimum length
// of a sub-array which contains
// {0, 1, 2, 3, 4} as a sub-sequence
int solve(int Array[], int N)
{
    // To store the indices where 0, 1, 2,
    // 3 and 4 are present
    vector<int> pos[5];
  
    // To store if there exist a valid prefix
    // of sequence in array
    int pref[5] = { 0 };
  
    // Base Case
    if (Array[0] == 0) {
        pref[0] = 1;
        pos[0].push_back(0);
    }
  
    int ans = MAX_INT;
  
    for (int i = 1; i < N; i++) {
  
        // If current element is 0
        if (Array[i] == 0) {
  
            // Update the count of 0s till now
            pref[0]++;
  
            // Push the index of the new 0
            pos[0].push_back(i);
        }
        else {
  
            // To check if previous element of the
            // given sequence is found till now
            if (pref[Array[i] - 1] > 0) {
                pref[Array[i]]++;
                pos[Array[i]].push_back(i);
  
                // If it is the end of sequence
                if (Array[i] == 4) {
                    int end = i;
                    int start = i;
  
                    // Iterate for other elements of the sequence
                    for (int j = 3; j >= 0; j--) {
                        int s = 0;
                        int e = pos[j].size() - 1;
                        int temp = -1;
  
                        // Binary Search to find closest occurrence
                        // less than equal to starting point
                        while (s <= e) {
                            int m = (s + e) / 2;
                            if (pos[j][m] <= start) {
                                temp = pos[j][m];
                                s = m + 1;
                            }
                            else {
                                e = m - 1;
                            }
                        }
  
                        // Update the starting point
                        start = temp;
                    }
  
                    ans = min(ans, end - start + 1);
                }
            }
        }
    }
  
    return ans;
}
  
// Driver code
int main()
{
    int Array[] = { 0, 1, 2, 3, 4, 2, 0, 3, 4 };
    int N = sizeof(Array) / sizeof(Array[0]);
  
    cout << solve(Array, N);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
class GFG 
{
static int MAX_INT = 1000000;
  
// Function to return the minimum length
// of a sub-array which contains
// {0, 1, 2, 3, 4} as a sub-sequence
static int solve(int[] array, int N) 
{
  
    // To store the indices where 0, 1, 2,
    // 3 and 4 are present
    int[][] pos = new int[5][10000];
  
    // To store if there exist a valid prefix
    // of sequence in array
    int[] pref = new int[5];
  
    // Base Case
    if (array[0] == 0)
    {
        pref[0] = 1;
        pos[0][pos[0].length - 1] = 0;
    }
  
    int ans = MAX_INT;
  
    for (int i = 1; i < N; i++) 
    {
  
        // If current element is 0
        if (array[i] == 0
        {
  
            // Update the count of 0s till now
            pref[0]++;
  
            // Push the index of the new 0
            pos[0][pos[0].length - 1] = i;
        
          
        else 
        {
  
            // To check if previous element of the
            // given sequence is found till now
            if (pref[array[i] - 1] > 0
            {
                pref[array[i]]++;
                pos[array[i]][pos[array[i]].length - 1] = i;
  
                // If it is the end of sequence
                if (array[i] == 4)
                {
                    int end = i;
                    int start = i;
  
                    // Iterate for other elements of the sequence
                    for (int j = 3; j >= 0; j--) 
                    {
                        int s = 0;
                        int e = pos[j].length - 1;
                        int temp = -1;
  
                        // Binary Search to find closest occurrence
                        // less than equal to starting point
                        while (s <= e) 
                        {
                            int m = (s + e) / 2;
                            if (pos[j][m] <= start) 
                            {
                                temp = pos[j][m];
                                s = m + 1;
                            
                            else
                                e = m - 1;
                        }
  
                        // Update the starting point
                        start = temp;
                    }
                    ans = Math.min(ans, end - start + 1);
                }
            }
        }
    }
    return ans;
}
  
// Driver Code
public static void main(String[] args)
{
    int[] array = { 0, 1, 2, 3, 4, 2, 0, 3, 4 };
    int N = array.length;
  
    System.out.println(solve(array, N));
}
}
  
// This code is contributed by
// sanjeev2552

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach
  
MAX_INT=1000000
  
# Function to return the minimum length
# of a sub-array which contains
# 0, 1, 2, 3, 4 as a sub-sequence
def solve(Array, N):
  
    # To store the indices where 0, 1, 2,
    # 3 and 4 are present
    pos=[[] for i in range(5)]
  
    # To store if there exist a valid prefix
    # of sequence in array
    pref=[0 for i in range(5)] 
  
    # Base Case
    if (Array[0] == 0): 
        pref[0] = 1
        pos[0].append(0)
      
  
    ans = MAX_INT
  
    for i in range(N): 
  
        # If current element is 0
        if (Array[i] == 0): 
  
            # Update the count of 0s till now
            pref[0]+=1
  
            # Push the index of the new 0
            pos[0].append(i)
          
        else :
  
            # To check if previous element of the
            # given sequence is found till now
            if (pref[Array[i] - 1] > 0): 
                pref[Array[i]]+=1
                pos[Array[i]].append(i)
  
                # If it is the end of sequence
                if (Array[i] == 4) :
                    end = i
                    start = i
  
                    # Iterate for other elements of the sequence
                    for j in range(3,-1,-1): 
                        s = 0
                        e = len(pos[j]) - 1
                        temp = -1
  
                        # Binary Search to find closest occurrence
                        # less than equal to starting point
                        while (s <= e): 
                            m = (s + e) // 2
                            if (pos[j][m] <= start) :
                                temp = pos[j][m]
                                s = m + 1
                              
                            else :
                                e = m - 1
                              
                          
  
                        # Update the starting point
                        start = temp
                      
  
                    ans = min(ans, end - start + 1)
                  
              
          
      
  
    return ans
  
# Driver code
  
Array = [ 0, 1, 2, 3, 4, 2, 0, 3, 4
N = len(Array)
  
print(solve(Array, N))
  
# This code is contributed by mohit kumar 29

chevron_right


Output:

5


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.