Find minimum length sub-array which has given sub-sequence in it
Last Updated :
18 Jan, 2023
Given an array arr[] of N elements, the task is to find the length of the smallest sub-array which has the 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
The required Subarray is {0, 1, 2, 3, 4} with minimum length.
The entire array also includes 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 the 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 the end as well as the start point and for all other numbers in sequence from 3 to 0. Apply binary search to find the closest index to the next element of the sequence, which will give us the size of the current valid sub-array.
- The 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++
#include <bits/stdc++.h>
using namespace std;
#define MAX_INT 1000000
int solve( int Array[], int N)
{
vector< int > pos[5];
int pref[5] = { 0 };
if (Array[0] == 0) {
pref[0] = 1;
pos[0].push_back(0);
}
int ans = MAX_INT;
for ( int i = 1; i < N; i++) {
if (Array[i] == 0) {
pref[0]++;
pos[0].push_back(i);
}
else {
if (pref[Array[i] - 1] > 0) {
pref[Array[i]]++;
pos[Array[i]].push_back(i);
if (Array[i] == 4) {
int end = i;
int start = i;
for ( int j = 3; j >= 0; j--) {
int s = 0;
int e = pos[j].size() - 1;
int temp = -1;
while (s <= e) {
int m = (s + e) / 2;
if (pos[j][m] <= start) {
temp = pos[j][m];
s = m + 1;
}
else {
e = m - 1;
}
}
start = temp;
}
ans = min(ans, end - start + 1);
}
}
}
}
return ans;
}
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;
}
|
Java
class GFG {
static int MAX_INT = 1000000 ;
static int solve( int [] array, int N)
{
int [][] pos = new int [ 5 ][ 10000 ];
int [] pref = new int [ 5 ];
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 (array[i] == 0 ) {
pref[ 0 ]++;
pos[ 0 ][pos[ 0 ].length - 1 ] = i;
}
else {
if (pref[array[i] - 1 ] > 0 ) {
pref[array[i]]++;
pos[array[i]][pos[array[i]].length - 1 ]
= i;
if (array[i] == 4 ) {
int end = i;
int start = i;
for ( int j = 3 ; j >= 0 ; j--) {
int s = 0 ;
int e = pos[j].length - 1 ;
int temp = - 1 ;
while (s <= e) {
int m = (s + e) / 2 ;
if (pos[j][m] <= start) {
temp = pos[j][m];
s = m + 1 ;
}
else
e = m - 1 ;
}
start = temp;
}
ans = Math.min(ans,
end - start + 1 );
}
}
}
}
return ans;
}
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));
}
}
|
Python3
MAX_INT = 1000000
def solve(Array, N):
pos = [[] for i in range ( 5 )]
pref = [ 0 for i in range ( 5 )]
if (Array[ 0 ] = = 0 ):
pref[ 0 ] = 1
pos[ 0 ].append( 0 )
ans = MAX_INT
for i in range (N):
if (Array[i] = = 0 ):
pref[ 0 ] + = 1
pos[ 0 ].append(i)
else :
if (pref[Array[i] - 1 ] > 0 ):
pref[Array[i]] + = 1
pos[Array[i]].append(i)
if (Array[i] = = 4 ):
end = i
start = i
for j in range ( 3 , - 1 , - 1 ):
s = 0
e = len (pos[j]) - 1
temp = - 1
while (s < = e):
m = (s + e) / / 2
if (pos[j][m] < = start):
temp = pos[j][m]
s = m + 1
else :
e = m - 1
start = temp
ans = min (ans, end - start + 1 )
return ans
Array = [ 0 , 1 , 2 , 3 , 4 , 2 , 0 , 3 , 4 ]
N = len (Array)
print (solve(Array, N))
|
C#
using System;
class GFG {
static int MAX_INT = 1000000;
static int solve( int [] array, int N)
{
int [, ] pos = new int [5, 10000];
int [] pref = new int [5];
if (array[0] == 0) {
pref[0] = 1;
pos[0, pos.GetLength(0) - 1] = 0;
}
int ans = MAX_INT;
for ( int i = 1; i < N; i++) {
if (array[i] == 0) {
pref[0]++;
pos[0, pos.GetLength(0) - 1] = i;
}
else {
if (pref[array[i] - 1] > 0) {
pref[array[i]]++;
pos[array[i], pos.GetLength(1) - 1] = i;
if (array[i] == 4) {
int end = i;
int start = i;
for ( int j = 3; j >= 0; j--) {
int s = 0;
int e = pos.GetLength(1) - 1;
int temp = -1;
while (s <= e) {
int m = (s + e) / 2;
if (pos[j, m] <= start) {
temp = pos[j, m];
s = m + 1;
}
else
e = m - 1;
}
start = temp;
}
ans = Math.Min(ans,
end - start + 1);
}
}
}
}
return ans;
}
public static void Main(String[] args)
{
int [] array = { 0, 1, 2, 3, 4, 2, 0, 3, 4 };
int N = array.Length;
Console.WriteLine(solve(array, N));
}
}
|
Javascript
<script>
let MAX_INT = 1000000;
function solve(array,N)
{
let pos = new Array(5);
for (let i=0;i<5;i++)
{
pos[i]= new Array(10000);
for (let j=0;j<10000;j++)
{
pos[i][j]=0;
}
}
let pref = new Array(5);
for (let i=0;i<5;i++)
{
pref[i]=0;
}
if (array[0] == 0)
{
pref[0] = 1;
pos[0][pos[0].length - 1] = 0;
}
let ans = MAX_INT;
for (let i = 1; i < N; i++)
{
if (array[i] == 0)
{
pref[0]++;
pos[0][pos[0].length - 1] = i;
}
else
{
if (pref[array[i] - 1] > 0)
{
pref[array[i]]++;
pos[array[i]][pos[array[i]].length - 1] = i;
if (array[i] == 4)
{
let end = i;
let start = i;
for (let j = 3; j >= 0; j--)
{
let s = 0;
let e = pos[j].length - 1;
let temp = -1;
while (s <= e)
{
let m = Math.floor((s + e) / 2);
if (pos[j][m] <= start)
{
temp = pos[j][m];
s = m + 1;
}
else
e = m - 1;
}
start = temp;
}
ans = Math.min(ans, end - start + 1);
}
}
}
}
return ans;
}
let array=[0, 1, 2, 3, 4, 2, 0, 3, 4];
let N = array.length;
document.write(solve(array, N));
</script>
|
Time Complexity: O(n.log n)
Auxiliary Space: O(n)
Share your thoughts in the comments
Please Login to comment...