Given Q queries of type 1, 2, 3 and 4 as described below.

**Type-1:**Insert a number to the list.**Type-2:**Delete only one occurrence of a number if exists.**Type-3:**Print the least frequent element, if multiple elements exist then print the greatest among them.**Type-4:**Print the most frequent element, if multiple elements exist then print the smallest among them.

The task is to write a program to perform all the above queries.

**Examples:**

Input:

Query1: 1 6

Query2: 1 6

Query3: 1 7

Query4: 3

Query5: 1 7

Query6: 2 7

Query7: 1 7

Query8: 3

Query9: 4

Output:

7

7

6

While answering Query4, the frequency of 6 is 2 and that of

7 is 1, hence the least frequent element is 7.

In Query8, the least frequent element is 6 and 7, so print the largest.

In Query9, the most frequent element is 6 and 7, so print the smallest.

A **naive approach** is to use any Data-Structures(array, vector, ..) and store all the elements. Using a hash-table, the frequency of every element can be stored. While processing the Query of type-2, delete one occurrence of that element from the DS in which the element has been stored. The queries of type-3 and type-4 can be answered by traversing the hash-table. The time complexity will be **O(N)** per query, where N is the number of elements till then in the DS.

An **efficient approach** will be to use set container to answer every query. Using two sets, one hash-table the above problem can be solved in **O(log n)** per query. Two sets *s1* and *s2* are used, one stores the * {num, frequency}*, while the other stores the

*. A hash-map is used which stores the frequency of each number. Design the set s2 using operator overloading such that it is sorted in ascending order of the first elements. If the first element appears to be same of one or more element, the set will be sorted in descending order of the second elements. The user-defined operating-overloading function thus will be:*

**{frequency, number}**bool operator<(pr a, pr b) { if(a.first == b.first) return a.second > b.second; return a.first < b.first; }Note:Operator overloading only works with user-defined data-types.pris a struct which has first and second as two integers.

Below is the algorithm to solve query of every type:

**Type1:**Check using hash-table if the element exists. If it does not exist, then mark the number in hash-table. Insert**{num, 1}**in set s1 and**{1, num}**in set2 using insert(). If it exists previously, then get the frequency from hash-table and delete**{num, frequency}**from set1 and**{frequency, num}**from set2 using find() and erase() function. Insert**{num, frequency+1}**in set1 and**{frequency+1, num}**in set2. Also, increase the count in hash-table.**Type2:**Follow the same process as above in query type1. Ony difference is to decrease the count in hash-table and insert**{num, frequency-1}**in set1 and**{frequency-1, num}**in set2.**Type3:**Print the beginning element which can be obtained using begin() function, as the set has been designed in such a way that begin() returns the least frequent element. If there are more than one, then it returns the largest.**Type4:**Print the last element in the set which can be obtained using rbegin() function in set.

Below is the implementation of the above approach:

`// C++ program for performing ` `// Queries of insert, delete one ` `// occurrence of a number and ` `// print the least and most frequent element ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// user-defined data-types ` `struct` `pr { ` ` ` `int` `first; ` ` ` `int` `second; ` `}; ` ` ` `// user-defined function to ` `// design a set ` `bool` `operator<(pr a, pr b) ` `{ ` ` ` `if` `(a.first == b.first) ` ` ` `return` `a.second > b.second; ` ` ` `return` `a.first < b.first; ` `} ` ` ` `// declare a user-defined set ` `set<pr> s1, s2; ` ` ` `// hash map ` `unordered_map<` `int` `, ` `int` `> m; ` ` ` `// Function to process the query ` `// of type-1 ` `void` `type1(` `int` `num) ` `{ ` ` ` ` ` `// if the element is already there ` ` ` `if` `(m[num]) { ` ` ` ` ` `// get the frequency of the element ` ` ` `int` `cnt = m[num]; ` ` ` ` ` `// returns an iterator pointing to ` ` ` `// position where the pair is ` ` ` `auto` `it1 = s1.find({ num, cnt }); ` ` ` `auto` `it2 = s2.find({ cnt, num }); ` ` ` ` ` `// deletes the pair from sets ` ` ` `s1.erase(it1); ` ` ` `s2.erase(it2); ` ` ` ` ` `// re-insert the pair by increasing ` ` ` `// frequency ` ` ` `s1.insert({ num, m[num] + 1 }); ` ` ` `s2.insert({ m[num] + 1, num }); ` ` ` `} ` ` ` ` ` `// if the element is not there in the list ` ` ` `else` `{ ` ` ` ` ` `// insert the element with frequency 1 ` ` ` `s1.insert({ num, 1 }); ` ` ` `s2.insert({ 1, num }); ` ` ` `} ` ` ` ` ` `// increase the count in hash-table ` ` ` `m[num] += 1; ` `} ` ` ` `// Function to process the query ` `// of type-2 ` `void` `type2(` `int` `num) ` `{ ` ` ` `// if the element exists ` ` ` `if` `(m[num]) { ` ` ` ` ` `// get the frequency of the element ` ` ` `int` `cnt = m[num]; ` ` ` ` ` `// returns an iterator pointing to ` ` ` `// position where the pair is ` ` ` `auto` `it1 = s1.find({ num, cnt }); ` ` ` `auto` `it2 = s2.find({ cnt, num }); ` ` ` ` ` `// deletes the pair from sets ` ` ` `s1.erase(it1); ` ` ` `s2.erase(it2); ` ` ` ` ` `// re-insert the pair by increasing ` ` ` `// frequency ` ` ` `s1.insert({ num, m[num] - 1 }); ` ` ` `s2.insert({ m[num] - 1, num }); ` ` ` ` ` `// decrease the count ` ` ` `m[num] -= 1; ` ` ` `} ` `} ` ` ` `// Function to process the query ` `// of type-3 ` `int` `type3() ` `{ ` ` ` `// if the set is not empty ` ` ` `// return the first element ` ` ` `if` `(!s1.empty()) { ` ` ` `auto` `it = s2.begin(); ` ` ` `return` `it->second; ` ` ` `} ` ` ` ` ` `else` ` ` `return` `-1; ` `} ` ` ` `// Function to process the query ` `// of type-4 ` `int` `type4() ` `{ ` ` ` ` ` `// if the set is not empty ` ` ` `// return the last element ` ` ` `if` `(!s1.empty()) { ` ` ` `auto` `it = s2.rbegin(); ` ` ` `return` `it->second; ` ` ` `} ` ` ` ` ` `else` ` ` `return` `-1; ` `} ` `// Driver Code ` `int` `main() ` `{ ` ` ` ` ` `// Queries ` ` ` ` ` `// inserts 6, 6 and 7 ` ` ` `type1(6); ` ` ` `type1(6); ` ` ` `type1(7); ` ` ` ` ` `// print the answer to query of type3 ` ` ` `cout << type3() << endl; ` ` ` ` ` `// inserts 7 ` ` ` `type1(7); ` ` ` ` ` `// deletes one occurrence of 7 ` ` ` `type2(7); ` ` ` ` ` `// inserts 7 ` ` ` `type1(7); ` ` ` ` ` `// print the answer to query of type3 ` ` ` `cout << type3() << endl; ` ` ` ` ` `// print the answer to query of type4 ` ` ` `cout << type4() << endl; ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

7 7 6

**Time Complexity:** O(log N) per query.

**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.

## Recommended Posts:

- Most frequent element in Array after replacing given index by K for Q queries
- Smallest subarray with all occurrences of a most frequent element
- Most frequent element in an array
- Group multiple occurrence of array elements ordered by first occurrence
- Find the most frequent digit without using array/string
- Find top k (or most frequent) numbers in a stream
- Most frequent word in an array of strings
- Kth most frequent Character in a given String
- Find k most frequent in linear time
- Count all elements in the array which appears at least K times after their first occurrence
- Design a data structure that supports insert, delete, search and getRandom in constant time
- Print array elements that are divisible by at-least one other
- Count elements that are divisible by at-least one element in another array
- Count pairs (p, q) such that p occurs in array at least q times and q occurs at least p times
- Minimize the length of string by removing occurrence of only one character
- Perform append, update, delete and range sum queries on the given array
- Check if a string can be split into two strings with same number of K-frequent characters
- Print characters and their frequencies in order of occurrence using a LinkedHashMap in Java
- Insert N elements in a Linked List one after other at middle position
- Print the last occurrence of elements in array in relative order

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.