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: 3
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: 4
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
- Finally, compute the Prefix sum of the array to compute the final array after the queries. Then use Two pointers approach to get the minimum length subarray containing all unique elements.
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 previously // 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 previously // 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 previously # 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 previously // 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 maintain previously // 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 maintain counter // of encountered elements let repeat = Array.from({length: count + 1}, (_, i) => 0); // variable to store answer let ans = N; // Using two pointers 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> |
4
Time Complexity: O(N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!