Skip to content
Related Articles

Related Articles

Improve Article
Minimum length subarray containing all unique elements after Q operations
  • Difficulty Level : Expert
  • Last Updated : 02 Jun, 2021

Given an array of size N containing all elements as 0 initially, and a Q queries containing range in the form of [L, R]. The task is to modify the array by adding 1 to each element in the range [L, R] for Q queries and then print the size of minimum length subarray containing all unique elements.
Note: 1-based indexing is used in the range [L, R].
Examples:

Input: N = 6, Q[4][] = {{1, 3}, {4, 6}, {3, 4}, {3, 3}} 
Output:
Explanation: 
Initial array: arr[] = { 0, 0, 0, 0, 0, 0 } 
Query 1: updated arr[] = { 1, 1, 1, 0, 0, 0 }. 
Query 2: updated arr[] = { 1, 1, 1, 1, 1, 1 }. 
Query 3: updated arr[] = { 1, 1, 2, 2, 1, 1 }. 
Query 4: updated arr[] = { 1, 1, 3, 2, 1, 1 }. 
The subarray { 1, 3, 2 } is minimum subarray which contains all unique elements. Thus, the answer is 3.
Input: N = 8, Q[6][] = {{1, 4}, {3, 4}, {4, 5}, {5, 5}, {7, 8}, {8, 8}} 
Output:
Explanation: 
After processing all queries, the array becomes = { 1, 1, 2, 3, 2, 0, 1, 2 }. 
The subarray { 3, 2, 0, 1 } is minimum subarray which contains all unique elements. Thus, the answer is 4.

Approach: The idea is to use the concept of Prefix sum array and Two pointers approach to this problem. 

  • Final Array after the queries can be computed by incrementing the value at the array by 1 at the index L and decrementing the value by 1 at the index R + 1.
Processing of a Query:
arr[L] += 1
arr[R + 1] -= 1

Below is the implementation of the above approach:

C++




// C++ implementation to find the
// minimum size subarray containing
// all unique elements after processing
// the array for K queries of ranges
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find minimum size subarray
// of all array elements
int subarrayLength(int A[], int R[][2],
                   int N, int M)
{
 
    // Updating the array after
    // processing each query
    for (int i = 0; i < M; ++i) {
 
        int l = R[i][0], r = R[i][1] + 1;
 
        // Making it to 0-indexing
        l--;
        r--;
 
        // Prefix sum array concept is used
        // to obtain the count array
        A[l]++;
 
        if (r < N)
            A[r]--;
    }
 
    // Iterating over the array
    // to get the final array
    for (int i = 1; i < N; ++i) {
        A[i] += A[i - 1];
    }
 
    // Variable to get count
    // of all unique elements
    int count = 0;
 
    // Hash to maintain perviously
    // occurred elements
    unordered_set<int> s;
 
    // Loop to find the all
    // unique elements
    for (int i = 0; i < N; ++i) {
        if (s.find(A[i]) == s.end())
            count++;
 
        s.insert(A[i]);
    }
 
    // array to maintain counter
    // of encountered elements
    vector<int> repeat(count + 1, 0);
 
    // variable to store answer
    int ans = N;
 
    // Using two pointers approach
    int counter = 0, left = 0, right = 0;
 
    while (right < N) {
 
        int cur_element = A[right];
        repeat[cur_element] += 1;
 
        // Increment counter
        // if occurred once
        if (repeat[cur_element] == 1)
            ++counter;
 
        // when all unique
        // elements are found
        while (counter == count) {
 
            // update answer with
            // minimum size
            ans = min(ans, right - left + 1);
 
            // decrement count of
            // elements from left
            cur_element = A[left];
            repeat[cur_element] -= 1;
            ++left;
 
            // decrement counter
            if (repeat[cur_element] == 0)
                --counter;
        }
 
        ++right;
    }
    return ans;
}
 
// Driver code
int main()
{
    int N = 8, queries = 6;
    int Q[][2]
        = {
            { 1, 4 }, { 3, 4 }, { 4, 5 },
            { 5, 5 }, { 7, 8 }, { 8, 8 }
          };
 
    int A[N] = { 0 };
 
    cout << subarrayLength(A, Q, N, queries);
 
    return 0;
}

Java




// Java implementation to find the
// minimum size subarray containing
// all unique elements after processing
// the array for K queries of ranges
import java.util.*;
class GFG{
 
// Function to find minimum size subarray
// of all array elements
static int subarrayLength(int A[], int R[][],
                          int N, int M)
{
    // Updating the array after
    // processing each query
    for (int i = 0; i < M; ++i)
    {
        int l = R[i][0], r = R[i][1] + 1;
 
        // Making it to 0-indexing
        l--;
        r--;
 
        // Prefix sum array concept is used
        // to obtain the count array
        A[l]++;
 
        if (r < N)
            A[r]--;
    }
 
    // Iterating over the array
    // to get the final array
    for (int i = 1; i < N; ++i)
    {
        A[i] += A[i - 1];
    }
 
    // Variable to get count
    // of all unique elements
    int count = 0;
 
    // Hash to maintain perviously
    // occurred elements
    HashSet<Integer> s = new HashSet<Integer>();
 
    // Loop to find the all
    // unique elements
    for (int i = 0; i < N; ++i)
    {
        if (!s.contains(A[i]))
            count++;
        s.add(A[i]);
    }
 
    // array to maintain counter
    // of encountered elements
    int []repeat = new int[count + 1];
 
    // variable to store answer
    int ans = N;
 
    // Using two pointers approach
    int counter = 0, left = 0, right = 0;
 
    while (right < N)
    {
        int cur_element = A[right];
        repeat[cur_element] += 1;
 
        // Increment counter
        // if occurred once
        if (repeat[cur_element] == 1)
            ++counter;
 
        // when all unique
        // elements are found
        while (counter == count)
        {
            // update answer with
            // minimum size
            ans = Math.min(ans,
                           right - left + 1);
 
            // decrement count of
            // elements from left
            cur_element = A[left];
            repeat[cur_element] -= 1;
            ++left;
 
            // decrement counter
            if (repeat[cur_element] == 0)
                --counter;
        }
 
        ++right;
    }
    return ans;
}
 
// Driver code
public static void main(String[] args)
{
    int N = 8, queries = 6;
    int Q[][] = {{ 1, 4 }, { 3, 4 }, { 4, 5 },
                 { 5, 5 }, { 7, 8 }, { 8, 8 }};
    int A[] = new int[N];
    System.out.print(subarrayLength(A, Q,
                                    N, queries));
}
}
 
// This code is contributed by Rajput-Ji

Python3




# Python3 implementation to find the
# minimum size subarray containing
# all unique elements after processing
# the array for K queries of ranges
 
# Function to find minimum size subarray
# of all array elements
def subarrayLength(A, R, N, M):
 
    # Updating the array after
    # processing each query
    for i in range(M):
 
        l = R[i][0]
        r = R[i][1] + 1
 
        # Making it to 0-indexing
        l -= 1
        r -= 1
 
        # Prefix sum array concept is used
        # to obtain the count array
        A[l] += 1
 
        if (r < N):
            A[r] -= 1
 
    # Iterating over the array
    # to get the final array
    for i in range(1 , N):
        A[i] += A[i - 1]
 
    # Variable to get count
    # of all unique elements
    count = 0
 
    # Hash to maintain perviously
    # occurred elements
    s = []
 
    # Loop to find the all
    # unique elements
    for i in range(N):
        if (A[i] not in s):
            count += 1
 
        s.append(A[i])
 
    # Array to maintain counter
    # of encountered elements
    repeat = [0] * (count + 1)
 
    # Variable to store answer
    ans = N
 
    # Using two pointers approach
    counter, left, right = 0, 0, 0
 
    while (right < N):
 
        cur_element = A[right]
        repeat[cur_element] += 1
 
        # Increment counter
        # if occurred once
        if (repeat[cur_element] == 1):
            counter += 1
 
        # When all unique
        # elements are found
        while (counter == count):
 
            # update answer with
            # minimum size
            ans = min(ans, right - left + 1)
 
            # Decrement count of
            # elements from left
            cur_element = A[left]
            repeat[cur_element] -= 1
            left += 1
 
            # Decrement counter
            if (repeat[cur_element] == 0):
                counter -= 1
                 
        right += 1
         
    return ans
 
# Driver code
if __name__ == "__main__":
     
    N , queries = 8 , 6
    Q = [ [ 1, 4 ], [ 3, 4 ], [ 4, 5 ],
          [ 5, 5 ], [ 7, 8 ], [ 8, 8 ] ]
 
    A = [0] * N
    print(subarrayLength(A, Q, N, queries))
 
# This code is contributed by chitranayal

C#




// C# implementation to find the
// minimum size subarray containing
// all unique elements after processing
// the array for K queries of ranges
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to find minimum size subarray
// of all array elements
static int subarrayLength(int []A, int [,]R,
                          int N, int M)
{
     
    // Updating the array after
    // processing each query
    for(int i = 0; i < M; ++i)
    {
        int l = R[i, 0], r = R[i, 1] + 1;
 
        // Making it to 0-indexing
        l--;
        r--;
 
        // Prefix sum array concept is used
        // to obtain the count array
        A[l]++;
 
        if (r < N)
            A[r]--;
    }
 
    // Iterating over the array
    // to get the readonly array
    for(int i = 1; i < N; ++i)
    {
        A[i] += A[i - 1];
    }
 
    // Variable to get count
    // of all unique elements
    int count = 0;
 
    // Hash to maintain perviously
    // occurred elements
    HashSet<int> s = new HashSet<int>();
 
    // Loop to find the all
    // unique elements
    for(int i = 0; i < N; ++i)
    {
        if (!s.Contains(A[i]))
            count++;
             
        s.Add(A[i]);
    }
 
    // Array to maintain counter
    // of encountered elements
    int []repeat = new int[count + 1];
 
    // Variable to store answer
    int ans = N;
 
    // Using two pointers approach
    int counter = 0, left = 0, right = 0;
 
    while (right < N)
    {
        int cur_element = A[right];
        repeat[cur_element] += 1;
 
        // Increment counter
        // if occurred once
        if (repeat[cur_element] == 1)
            ++counter;
 
        // When all unique
        // elements are found
        while (counter == count)
        {
             
            // Update answer with
            // minimum size
            ans = Math.Min(ans,
                           right - left + 1);
 
            // Decrement count of
            // elements from left
            cur_element = A[left];
            repeat[cur_element] -= 1;
            ++left;
 
            // Decrement counter
            if (repeat[cur_element] == 0)
                --counter;
        }
        ++right;
    }
    return ans;
}
 
// Driver code
public static void Main(String[] args)
{
    int N = 8, queries = 6;
    int [,]Q = { { 1, 4 }, { 3, 4 }, { 4, 5 },
                 { 5, 5 }, { 7, 8 }, { 8, 8 } };
    int []A = new int[N];
     
    Console.Write(subarrayLength(A, Q,
                                 N, queries));
}
}
 
// This code is contributed by Amit Katiyar

Javascript




<script>
 
// Javascript implementation to find the
// minimum size subarray containing
// all unique elements after processing
// the array for K queries of ranges
 
// Function to find minimum size subarray
// of all array elements
function subarrayLength(A, R, N, M)
{
    // Updating the array after
    // processing each query
    for (let i = 0; i < M; ++i)
    {
        let l = R[i][0], r = R[i][1] + 1;
   
        // Making it to 0-indexing
        l--;
        r--;
   
        // Prefix sum array concept is used
        // to obtain the count array
        A[l]++;
   
        if (r < N)
            A[r]--;
    }
   
    // Iterating over the array
    // to get the final array
    for (let i = 1; i < N; ++i)
    {
        A[i] += A[i - 1];
    }
   
    // Variable to get count
    // of all unique elements
    let count = 0;
   
    // Hash to maletain perviously
    // occurred elements
    let s = new Set();
   
    // Loop to find the all
    // unique elements
    for (let i = 0; i < N; ++i)
    {
        if (!s.has(A[i]))
            count++;
        s.add(A[i]);
    }
   
    // array to maletain counter
    // of encountered elements
    let repeat = Array.from({length: count + 1}, (_, i) => 0);
   
    // variable to store answer
    let ans = N;
   
    // Using two poleters approach
    let counter = 0, left = 0, right = 0;
   
    while (right < N)
    {
        let cur_element = A[right];
        repeat[cur_element] += 1;
   
        // Increment counter
        // if occurred once
        if (repeat[cur_element] == 1)
            ++counter;
   
        // when all unique
        // elements are found
        while (counter == count)
        {
            // update answer with
            // minimum size
            ans = Math.min(ans,
                           right - left + 1);
   
            // decrement count of
            // elements from left
            cur_element = A[left];
            repeat[cur_element] -= 1;
            ++left;
   
            // decrement counter
            if (repeat[cur_element] == 0)
                --counter;
        }
   
        ++right;
    }
    return ans;
}
 
// Driver code
     
      let N = 8, queries = 6;
    let Q = [[ 1, 4 ], [ 3, 4 ], [ 4, 5 ],
                 [ 5, 5 ], [ 7, 8 ], [ 8, 8 ]];
    let A = Array.from({length: N}, (_, i) => 0);
    document.write(subarrayLength(A, Q,
                                    N, queries));
                                                                                      
</script>
Output: 



4

Time Complexity: O(N) 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer DSA Live Classes




My Personal Notes arrow_drop_up
Recommended Articles
Page :