Related Articles

# Find the maximum length of the prefix | Set-2

• Last Updated : 15 Jul, 2021

Given an array arr[] of N integers, the task is to find the maximum prefix length of the array such that removing exactly one element from the prefix will make the frequency of the remaining prefix elements the same.

Examples:

Input: arr[] = {1, 1, 1, 2, 2, 2}
Output: 5
Explanation:
The following prefixes satisfy the given conditions:

1. The prefix over the range [0, 0]. Removing the only element in the prefix will become empty.
2. The prefix over the range [0, 1]. Removing either of the element from the prefix, frequency of every element will becomes equal in the prefix.
3. The prefix over the range [0, 2]. Removing any of the element from the prefix, frequency of every element will becomes equal in the prefix.
4. The prefix over the range [0, 3]. Removing the element at index 3 from the prefix, frequency of every element will becomes equal in the prefix.
5. The prefix over the range [0, 4]. Removing any element in the range [0, 2] from the prefix, frequency of every element will becomes equal in the prefix.

Therefore, the maximum length of prefix satisfying the conditions is 5.

Input: arr[] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5}
Output: 13

The Hashing and sorting-based approach has been discussed in Set 1 of this article.

Approach: The idea is to use two Maps to keep track of the frequencies of elements and use the following four conditions to check for valid prefixes.

1. Frequencies of all the elements of the prefix are equal to 1.
2. All the elements in the prefix window are the same.
3. There exist only two distinct frequencies of the elements in the prefix and the difference between them is equal to 1 and the count of the frequency with a larger value is 1.
4. There exists a single element with frequency 1 and except that all elements have the same frequency.

Follow the steps below to solve the problem:

• Initialize two Maps say mp1 and mp2 to store the frequency of elements in the prefix and to store the frequency of the frequencies of the elements respectively.
• Also, Initialize a variable say ans as 0 to store the maximum length of the prefix.
• Traverse over the range [0, N-1] using the variable i and follow the below steps:
• If the count of arr[i] is not equal to 0, then decrement the count of that frequency from the map mp2 and if it becomes 0 then erase the value from map mp2.
• Increment the count of arr[i] in the map mp1 by 1 and then increment the count of the new frequency of arr[i] i.e mp1[arr[i]] in Map mp2 by 1.
• If the count of the current element is equal to its prefix length i.e (i+1) or every element occurred once in the prefix then update the value of ans to max(ans, i+1).
• Now, if the size of mp2 is equal to 2 then perform the following steps,
• Store the frequencies of the array element i.e key of the map mp2 in variables say freq1 and freq2 respectively.
• Store the counts of frequencies of freq1 and freq2 in variables say count1 and count2.
• Check if the difference between freq2 and freq1 is equal to 1 and the value of count2 is equal to 1 then update the ans to max(ans, i+1).
• Else, if the difference between freq1 and freq2 is equal to 1 and the value of count1 is equal to 1 then update the ans to max(ans, i+1).
• Else if freq2 and count2 are equal to 1 or freq1 and count1 are equal to 1 then update the ans to max(ans, i+1).
• Finally, after completing the above steps print the value of ans.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to find the maximum``// length of the required prefix``int` `maxPrefixLen(``int` `arr[], ``int` `N)``{` `    ``// Stores the frequency of``    ``// elements``    ``unordered_map<``int``, ``int``> a, b;` `    ``// Stores the maximum length``    ``// of the prefix satisfying``    ``// the conditions``    ``int` `ans = 1;` `    ``// Traverse the array arr[]``    ``for` `(``int` `i = 0; i < N; i++) {` `        ``// Stores the count of``        ``// current element``        ``int` `curr = a[arr[i]];` `        ``// If curr is not``        ``// equal to 0``        ``if` `(curr != 0) {` `            ``// Decrement b[curr]``            ``// by 1``            ``b[curr]--;` `            ``// If b[curr] is 0``            ``if` `(b[curr] == 0) {``                ``// Remove b[curr]``                ``// from the b``                ``b.erase(curr);``            ``}``        ``}` `        ``// Update``        ``a[arr[i]]++;``        ``b[curr + 1]++;` `        ``// If all elements in the``        ``// prefix are same or if``        ``// all elements have frequency``        ``// 1``        ``if` `(a[arr[i]] == i + 1``            ``or (b.find(1) != b.end() and b == i + 1)) {``            ``// Update the value of ans``            ``ans = max(ans, i + 1);``        ``}` `        ``// Else if the size of b``        ``// is 2``        ``else` `if` `(b.size() == 2) {` `            ``auto` `p = b.begin();``            ``auto` `q = p;` `            ``// Increment q by 1``            ``q++;` `            ``int` `freq1 = p->first;``            ``int` `freq2 = q->first;` `            ``int` `count1 = p->second;``            ``int` `count2 = q->second;` `            ``// If difference between``            ``// freq2 and freq1 is``            ``// equal to 1 and if``            ``// count2 is equal to 1``            ``if` `(freq2 - freq1 == 1 and count2 == 1) {``                ``// Update the value``                ``// of ans``                ``ans = max(ans, i + 1);``            ``}` `            ``// If difference between``            ``// freq1 and freq2 is``            ``// equal to 1 and if``            ``// count1 is equal to 1``            ``else` `if` `(freq1 - freq2 == 1 and count1 == 1) {``                ``// Update the value``                ``// of ans``                ``ans = max(ans, i + 1);``            ``}``            ``// If freq2 and count2 is 1``            ``// or freq1 and count1 is 1``            ``if` `((freq2 == 1 and count2 == 1)``                ``or (freq1 == 1 and count1 == 1)) {``                ``// Update the value of``                ``// ans``                ``ans = max(ans, i + 1);``            ``}``        ``}``    ``}` `    ``// Return ans``    ``return` `ans;``}` `// Driver Code``int` `main()``{` `    ``int` `arr[] = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5 };``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);` `    ``cout << maxPrefixLen(arr, N);``}`

## Java

 `// Java program for the above approach``import` `java.util.HashMap;``class` `GFG {` `    ``// Function to find the maximum``    ``// length of the required prefix``    ``public` `static` `int` `maxPrefixLen(``int` `arr[], ``int` `N)``    ``{` `        ``// Stores the frequency of``        ``// elements``        ``HashMap a = ``new` `HashMap();``        ``HashMap b = ``new` `HashMap();` `        ``// Stores the maximum length``        ``// of the prefix satisfying``        ``// the conditions``        ``int` `ans = ``1``;` `        ``// Traverse the array arr[]``        ``for` `(``int` `i = ``0``; i < N; i++) {` `            ``// Stores the count of``            ``// current element``            ``int` `curr = !a.containsKey(arr[i]) ? ``0` `: a.get(arr[i]);` `            ``// If curr is not``            ``// equal to 0``            ``if` `(curr != ``0``) {` `                ``// Decrement b[curr]``                ``// by 1``                ``b.put(curr, b.get(curr) - ``1``);` `                ``// If b[curr] is 0``                ``if` `(b.get(curr) == ``0``)``                ``{``                  ` `                    ``// Remove b[curr]``                    ``// from the b``                    ``b.remove(curr);``                ``}``            ``}` `            ``// Update``            ``if` `(a.containsKey(arr[i])) {``                ``a.put(arr[i], a.get(arr[i]) + ``1``);``            ``} ``else` `{``                ``a.put(arr[i], ``1``);``            ``}` `            ``if` `(b.containsKey(curr + ``1``)) {``                ``b.put(curr + ``1``, b.get(curr + ``1``) + ``1``);``            ``} ``else` `{``                ``b.put(curr + ``1``, ``1``);``            ``}` `            ``// If all elements in the``            ``// prefix are same or if``            ``// all elements have frequency``            ``// 1``            ``if` `(a.get(arr[i]) == i + ``1` `|| (b.containsKey(``1``) && b.get(``1``) == i + ``1``))``            ``{``              ` `                ``// Update the value of ans``                ``ans = Math.max(ans, i + ``1``);``            ``}` `            ``else` `if` `(b.size() == ``2``) {` `                ``int` `p = b.keySet().toArray()[``0``].hashCode();``                ``int` `q = b.keySet().toArray()[``1``].hashCode();` `                ``// Increment q by 1` `                ``int` `freq1 = p;``                ``int` `freq2 = q;` `                ``int` `count1 = b.get(p);``                ``int` `count2 = b.get(q);` `                ``// If difference between``                ``// freq2 and freq1 is``                ``// equal to 1 and if``                ``// count2 is equal to 1``                ``if` `((freq2 - freq1) == ``1` `&& count2 == ``1``)``                ``{``                  ` `                    ``// Update the value``                    ``// of ans``                    ``ans = Math.max(ans, i + ``1``);``                ``}` `                ``// If difference between``                ``// freq1 and freq2 is``                ``// equal to 1 and if``                ``// count1 is equal to 1``                ``else` `if` `(freq1 - freq2 == ``1` `&& count1 == ``1``)``                ``{``                  ` `                    ``// Update the value``                    ``// of ans``                    ``ans = Math.max(ans, i + ``1``);``                ``}``                ``// If freq2 and count2 is 1``                ``// or freq1 and count1 is 1``                ``if` `((freq2 == ``1` `&& count2 == ``1``) || (freq1 == ``1` `&& count1 == ``1``))``                ``{``                  ` `                    ``// Update the value of``                    ``// ans``                    ``ans = Math.max(ans, i + ``1``);``                ``}``            ``}``        ``}``      ` `        ``// Return ans``        ``return` `ans;``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String args[]) {` `        ``int` `arr[] = { ``1``, ``1``, ``1``, ``2``, ``2``, ``2``, ``3``, ``3``, ``3``, ``4``, ``4``, ``4``, ``5` `};``        ``int` `N = arr.length;` `        ``System.out.println(maxPrefixLen(arr, N));``    ``}``}` `// This code is contributed by gfgking.`

## Python3

 `# Python3 program for the above approach` `# Function to find the maximum``# length of the required prefix``def` `maxPrefixLen(arr, N):` `    ``# Stores the frequency of``    ``# elements``    ``a, b ``=` `{}, {}` `    ``# Stores the maximum length``    ``# of the prefix satisfying``    ``# the conditions``    ``ans ``=` `1` `    ``# Traverse the array arr[]``    ``for` `i ``in` `range``(N):``        ` `        ``# Stores the count of``        ``# current element``        ``curr ``=` `0` `if` `(arr[i] ``not` `in` `a) ``else` `a[arr[i]]` `        ``# If curr is not``        ``# equal to 0``        ``if` `(curr !``=` `0``):``            ` `            ``# Decrement b[curr]``            ``# by 1``            ``b[curr] ``-``=` `1``            ` `            ``# If b[curr] is 0``            ``if` `(b[curr] ``=``=` `0``):``                ` `                ``# Remove b[curr]``                ``# from the b``                ``del` `b[curr]` `        ``# Update``        ``a[arr[i]] ``=` `a.get(arr[i], ``0``) ``+` `1``        ``b[curr ``+` `1``] ``=` `b.get(curr ``+` `1``, ``0``) ``+` `1`` ` `        ``# If all elements in the``        ``# prefix are same or if``        ``# all elements have frequency``        ``# 1``        ``if` `(a[arr[i]] ``=``=` `i ``+` `1` `or``           ``(``1` `in` `b) ``and` `b[``1``] ``=``=` `i ``+` `1``):``               ` `            ``# Update the value of ans``            ``ans ``=` `max``(ans, i ``+` `1``)` `        ``# Else if the size of b``        ``# is 2``        ``elif` `(``len``(b) ``=``=` `2``):``            ``p ``=` `list``(b.keys())[``0``]``            ``q ``=` `list``(b.keys())[``1``]` `            ``freq1 ``=` `p``            ``freq2 ``=` `q` `            ``count1 ``=` `b[p]``            ``count2 ``=` `b[q]``            ` `            ``# If difference between``            ``# freq2 and freq1 is``            ``# equal to 1 and if``            ``# count2 is equal to 1``            ``if` `(freq2 ``-` `freq1 ``=``=` `1` `and` `count2 ``=``=` `1``):``                ` `                ``# Update the value``                ``# of ans``                ``ans ``=` `max``(ans, i ``+` `1``)` `            ``# If difference between``            ``# freq1 and freq2 is``            ``# equal to 1 and if``            ``# count1 is equal to 1``            ``elif` `(freq1 ``-` `freq2 ``=``=` `1` `and` `count1 ``=``=` `1``):``                ` `                ``# Update the value``                ``# of ans``                ``ans ``=` `max``(ans, i ``+` `1``)``                ` `            ``# If freq2 and count2 is 1``            ``# or freq1 and count1 is 1``            ``if` `((freq2 ``=``=` `1` `and` `count2 ``=``=` `1``) ``or``                ``(freq1 ``=``=` `1` `and` `count1 ``=``=` `1``)):``                    ` `                ``# Update the value of``                ``# ans``                ``ans ``=` `max``(ans, i ``+` `1``)` `    ``# Return ans``    ``return` `ans` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ` `    ``arr ``=` `[ ``1``, ``1``, ``1``, ``2``, ``2``, ``2``, ``3``,``            ``3``, ``3``, ``4``, ``4``, ``4``, ``5` `]``    ``N ``=` `len``(arr)` `    ``print``(maxPrefixLen(arr, N))` `# This code is contributed by mohit kumar 29`

## Javascript

 ``
Output:
`13`

Time Complexity: O(N)
Auxiliary Space: 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 experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up