Related Articles

# Maximum occurring element in a subarray range (Mode queries)

• Difficulty Level : Medium
• Last Updated : 13 Aug, 2021

Given an array arr[] of N integers, and an array Q[] of M pairs, where a pair represents a query of the form {L, R}, the task is to find the maximum occurring element in the range [L, R] and its frequency for each query. If there are multiple elements with maximum frequency, then print the maximum element among them.

Examples:

Input: arr[] = {5, 7, 5, 5, 2, 7, 3, 2, 5, 2}, Q[] = {{0, 9}, {3, 6}, {4, 8}, {1, 5}}
Output: 5 Occurs 4 times
3 Occurs 1 times
2 Occurs 2 times
7 Occurs 2 times
Explanation:
The queries are performed as:

1. Query(0, 9): The subarray over the range is {5, 7, 5, 5, 2, 7, 3, 2, 5, 2}. Elements 5, 7, 2, and 3 occur 4, 2, 3 and 1 times respectively. Therefore, print 5.
2. Query(3, 6): The subarray over the range is {5, 2, 7, 3}. Every element occurs once. So print element 7.
3. Query(4, 8): The subarray over the range is {2, 7, 3, 2, 5}. Element 2 occurs twice and the remaining all occurs once. Therefore, print 2.
4. Query(1, 5): The subarray over the range is {7, 5, 5, 2, 7, 3}. Elements 7 and 5 occur twice and the remaining elements occur once. Therefore print 7.

Naive Approach: For each query, iterate over the given range [L, R] keep updating the frequency of every element in an auxiliary data structure (ex. map). After processing the entire range of the current query, iterate over all elements in the map, and find the element having the maximum frequency

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to find the elements having``// maximum frequency for the query range``void` `getMaxOccuringElement(``int` `arr[], ``int` `N, ``int` `M,``                           ``pair<``int``, ``int``> Q[])``{``    ``// Iterate over all the queries``    ``for` `(``int` `i = 0; i < M; ++i) {` `        ``// Stores the frequency of each element``        ``// in the current query range [l, r]``        ``map<``int``, ``int``> freq;` `        ``int` `l = Q[i].first, r = Q[i].second;` `        ``for` `(``int` `j = l; j <= r; ++j)``            ``++freq[arr[j]];` `        ``int` `maxFreqElement = -1;``        ``int` `maxFreq = -1;` `        ``// Iterate over the map and find the``        ``// element having maximum frequency``        ``for` `(``auto` `it : freq) {``            ``if` `(it.second >= maxFreq) {``                ``maxFreqElement = it.first;``                ``maxFreq = it.second;``            ``}``        ``}` `        ``// Print the answer for current query``        ``cout << maxFreqElement << ``" Occurs "` `<< maxFreq``             ``<< ``" times"` `<< endl;``    ``}``}` `// Driver Code``int` `main()``{` `    ``int` `arr[] = { 5, 7, 5, 5, 2, 7, 3, 2, 5, 2 };``    ``pair<``int``, ``int``> Q[]``        ``= { { 0, 9 }, { 3, 6 }, { 4, 8 }, { 1, 5 } };` `    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);``    ``int` `M = ``sizeof``(Q) / ``sizeof``(Q);` `    ``getMaxOccuringElement(arr, N, M, Q);` `    ``return` `0;``}`

## Java

 `// Java program for the above approach` `import` `java.util.*;` `class` `GFG{` `    ``static` `class` `pair``    ``{``        ``int` `first, second;``        ``public` `pair(``int` `first, ``int` `second) ``        ``{``            ``this``.first = first;``            ``this``.second = second;``        ``}   ``    ``}``// Function to find the elements having``// maximum frequency for the query range``static` `void` `getMaxOccuringElement(``int` `arr[], ``int` `N, ``int` `M,``                           ``pair Q[])``{``    ``// Iterate over all the queries``    ``for` `(``int` `i = ``0``; i < M; ++i) {` `        ``// Stores the frequency of each element``        ``// in the current query range [l, r]``        ``HashMap freq = ``new` `HashMap();` `        ``int` `l = Q[i].first, r = Q[i].second;` `        ``for` `(``int` `j = l; j <= r; ++j) {``            ``if``(freq.containsKey(arr[j]))``            ``freq.put(arr[j], freq.get(arr[j])+``1``);``            ``else``                ``freq.put(arr[j], ``1``);``                ` `        ``}` `        ``int` `maxFreqElement = -``1``;``        ``int` `maxFreq = -``1``;` `        ``// Iterate over the map and find the``        ``// element having maximum frequency``        ``for` `(Map.Entry it : freq.entrySet()) {``            ``if` `(it.getValue() >= maxFreq) {``                ``maxFreqElement = it.getKey();``                ``maxFreq = it.getValue();``            ``}``        ``}` `        ``// Print the answer for current query``        ``System.out.print(maxFreqElement+ ``" Occurs "` `+  maxFreq``            ``+ ``" times"` `+``"\n"``);``    ``}``}` `// Driver Code``public` `static` `void` `main(String[] args)``{` `    ``int` `arr[] = { ``5``, ``7``, ``5``, ``5``, ``2``, ``7``, ``3``, ``2``, ``5``, ``2` `};``    ``pair Q[]``        ``= { ``new` `pair( ``0``, ``9` `), ``new` `pair( ``3``, ``6` `), ``new` `pair( ``4``, ``8` `), ``new` `pair( ``1``, ``5` `) };` `    ``int` `N = arr.length;``    ``int` `M = Q.length;` `    ``getMaxOccuringElement(arr, N, M, Q);` `}``}` `// This code contributed by Princi Singh`

## C#

 `// C# program for the above approach``using` `System;``using` `System.Collections.Generic;` `public` `class` `GFG{` `    ``class` `pair``    ``{``        ``public` `int` `first, second;``        ``public` `pair(``int` `first, ``int` `second) ``        ``{``            ``this``.first = first;``            ``this``.second = second;``        ``}   ``    ``}``  ` `// Function to find the elements having``// maximum frequency for the query range``static` `void` `getMaxOccuringElement(``int` `[]arr, ``int` `N, ``int` `M,``                           ``pair []Q)``{``  ` `    ``// Iterate over all the queries``    ``for` `(``int` `i = 0; i < M; ++i) {` `        ``// Stores the frequency of each element``        ``// in the current query range [l, r]``        ``Dictionary<``int``,``int``> freq = ``new` `Dictionary<``int``,``int``>();` `        ``int` `l = Q[i].first, r = Q[i].second;` `        ``for` `(``int` `j = l; j <= r; ++j) {``            ``if``(freq.ContainsKey(arr[j]))``            ``freq[arr[j]] = freq[arr[j]]+1;``            ``else``                ``freq.Add(arr[j], 1);``                ` `        ``}` `        ``int` `maxFreqElement = -1;``        ``int` `maxFreq = -1;` `        ``// Iterate over the map and find the``        ``// element having maximum frequency``        ``foreach` `(KeyValuePair<``int``,``int``> it ``in` `freq) {``            ``if` `(it.Value >= maxFreq) {``                ``maxFreqElement = it.Key;``                ``maxFreq = it.Value;``            ``}``        ``}` `        ``// Print the answer for current query``        ``Console.Write(maxFreqElement+ ``" Occurs "` `+  maxFreq``            ``+ ``" times"` `+``"\n"``);``    ``}``}` `// Driver Code``public` `static` `void` `Main(String[] args)``{` `    ``int` `[]arr = { 5, 7, 5, 5, 2, 7, 3, 2, 5, 2 };``    ``pair []Q``        ``= { ``new` `pair( 0, 9 ), ``new` `pair( 3, 6 ), ``new` `pair( 4, 8 ), ``new` `pair( 1, 5 ) };` `    ``int` `N = arr.Length;``    ``int` `M = Q.Length;` `    ``getMaxOccuringElement(arr, N, M, Q);` `}``}` `// This code is contributed by 29AjayKumar`
Output
```5 Occurs 4 times
7 Occurs 1 times
2 Occurs 2 times
7 Occurs 2 times```

Time Complexity: O(M * N)
Auxiliary Space: O(N)

Efficient Approach: The above approach can be optimized by Mo’s Algorithm based on the concept of sqrt decomposition. Follow the steps below to solve the problem:

• The queries are sorted in non-decreasing order of the blocks in which their left index falls. If two or more queries have their left indexes in the same block, then order them based on their right indexes.
• Basically, compute the answer for all queries which have their left index in block 0, then block 1, and so on till the last block.
• Maintain a map data structure (num_freq) which stores the count of occurrence of each element in the current query range.
• Also, maintain a set data structure (freq_num), whose each element is a pair (the first element of the pair represents the count of occurrence of an element and the second element of the pair represents the element itself).
• The set(freq_num) stores the elements in non-decreasing order. The ordering of elements in the set is based on the first item of the pair, which represents the frequency.
• Thus, while answering the queries (i.e. the element having the maximum frequency), it can be done in O(1).

Below is the implementation of the above approach :

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `int` `BLOCK_SIZE;` `// Structure to represent a query range``// and its index``struct` `query {``    ``int` `l, r, idx;``};` `// Custom comparator``bool` `comparator(query a, query b)``{``    ``if` `((a.l / BLOCK_SIZE) != (b.l / BLOCK_SIZE))``        ``return` `(a.l / BLOCK_SIZE) < (b.l / BLOCK_SIZE);` `    ``return` `((a.l / BLOCK_SIZE) & 1) ? (a.r < b.r)``                                    ``: (a.r > b.r);``}` `// Function to add elements to the current range``void` `expand(``int` `idx, ``int``* arr, map<``int``, ``int``>& numFreq,``            ``set >& freqNum)``{``    ``// Remove current element from the set``    ``freqNum.erase({ numFreq[arr[idx]], arr[idx] });` `    ``// Increment current element count in the``    ``// map``    ``++numFreq[arr[idx]];` `    ``// Insert current element into the set``    ``freqNum.insert({ numFreq[arr[idx]], arr[idx] });``}` `// Function to remove elements from the current range``void` `shrink(``int` `idx, ``int``* arr, map<``int``, ``int``>& numFreq,``            ``set >& freqNum)``{``    ``// Remove current element from the set``    ``freqNum.erase({ numFreq[arr[idx]], arr[idx] });` `    ``// Decrement current element count in the``    ``// map``    ``--numFreq[arr[idx]];` `    ``// Insert current element into the set``    ``freqNum.insert({ numFreq[arr[idx]], arr[idx] });``}` `// Function for Mo's algorithm``pair<``int``, ``int``>``sqrtDecomposition(``int``& L, ``int``& R, ``int` `l, ``int` `r, ``int``* arr,``                  ``set >& freqNum,``                  ``map<``int``, ``int``>& numFreq)``{``    ``// Iterate until L is greater than l``    ``while` `(L > l) {``        ``--L;``        ``expand(L, arr, numFreq, freqNum);``    ``}` `    ``// Iterate until R is less than r``    ``while` `(R < r) {``        ``++R;``        ``expand(R, arr, numFreq, freqNum);``    ``}` `    ``// Iterate until L is less than l``    ``while` `(L < l) {``        ``shrink(L, arr, numFreq, freqNum);``        ``++L;``    ``}` `    ``// Iterate until R is greater than r``    ``while` `(R > r) {``        ``shrink(R, arr, numFreq, freqNum);``        ``--R;``    ``}` `    ``// Stores the answer for current query``    ``pair<``int``, ``int``> last = *prev(freqNum.end());` `    ``// Return the answer``    ``return` `last;``}` `// Function to find the element having maximum``// frequency and its frequency for all the queries``void` `getMaxOccuringElement(``int` `arr[], ``int` `N, ``int` `M,``                           ``pair<``int``, ``int``> Q[])``{` `    ``// Compute each block size``    ``BLOCK_SIZE = (``int``)``sqrt``(N + .0) + 1;` `    ``// Stores the queries``    ``query queries[M];` `    ``for` `(``int` `i = 0; i < M; ++i) {``        ``queries[i].l = Q[i].first;``        ``queries[i].r = Q[i].second;``        ``queries[i].idx = i;``    ``}` `    ``// Sort all the queries``    ``sort(queries, queries + M, comparator);` `    ``// Initiali ranges of Mos``    ``int` `L = 0, R = -1;` `    ``// Stores the answer``    ``pair<``int``, ``int``> ans[M];` `    ``set > freqNum;``    ``map<``int``, ``int``> numFreq;` `    ``// Traverse the query array``    ``for` `(``int` `i = 0; i < M; ++i) {` `        ``int` `l = queries[i].l;``        ``int` `r = queries[i].r;` `        ``// Stores the answer for current``        ``// query``        ``ans[queries[i].idx] = sqrtDecomposition(``            ``L, R, l, r, arr, freqNum, numFreq);``    ``}` `    ``// Print the answer``    ``for` `(``int` `i = 0; i < M; ++i) {``        ``cout << ans[i].second << ``" Occurs "` `<< ans[i].first``             ``<< ``" times"` `<< endl;``    ``}``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 5, 7, 5, 5, 2, 7, 3, 2, 5, 2 };``    ``pair<``int``, ``int``> Q[]``        ``= { { 0, 9 }, { 3, 6 }, { 4, 8 }, { 1, 5 } };` `    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);``    ``int` `M = ``sizeof``(Q) / ``sizeof``(Q);` `    ``getMaxOccuringElement(arr, N, M, Q);` `    ``return` `0;``}`
Output
```5 Occurs 4 times
7 Occurs 1 times
2 Occurs 2 times
7 Occurs 2 times```

Time Complexity: O((N+M) * log(N) * sqrt(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