Next Greater Frequency Element
Given an array arr[], for each element, find the nearest element to its right that has a higher frequency than the current element. If no such element exists, set the value to -1.
Examples:
Input: arr[] = [2, 1, 1, 3, 2, 1]
Output: [1, -1, -1, 2, 1, -1]
Explanation: Frequencies: 1 → 3 times, 2 → 2 times, 3 → 1 time.
For arr[0] = 2, the next element 1 has a higher frequency → 1.
For arr[1] and arr[2] (1), no element to the right has a higher frequency → -1.
For arr[3] = 3, the next 2 has a higher frequency → 2.
For arr[4] = 2, the next 1 has a higher frequency → 1.
For arr[5] = 1, no elements to the right → -1.Input: arr[] = [1, 2, 1]
Output: [-1, 1, -1]
Explanation: Frequencies: 1→2, 2→1.
2→1 (higher freq), others have no higher freq on right → [-1, 1, -1]
Table of Content
[Naive approach] Frequency Count and Nested Loop - O(n^2) Time and O(n) Space
The idea is to find, for each element, the next element to its right that has a higher frequency using a frequency map and a nested loop. If none exists, return -1.
Step By Step Implementations:
- Use a hash map to count occurrences of each element in one pass.
- Iterate through each element of the array.
- For each element, scan right to find the first with a higher frequency.
- Store the found element or
-1
if none is found.
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
vector<int> findGreater(const vector<int>& arr) {
// Calculate frequency of each element
// using a hash map (unordered_map).
unordered_map<int, int> freq;
for (int num : arr) {
freq[num]++;
}
vector<int> result;
for (int i = 0; i < arr.size(); i++) {
bool found = false;
// Inner loop to find the first element
// with a greater frequency
for (int j = i + 1; j < arr.size(); j++) {
if (freq[arr[j]] > freq[arr[i]]) {
result.push_back(arr[j]);
found = true;
break;
}
}
// If no element with a greater frequency
// is found, push -1
if (!found) {
result.push_back(-1);
}
}
return result;
}
int main() {
vector<int> arr = {2, 1, 1, 3, 2, 1};
vector<int> result = findGreater(arr);
for (int num : result) {
cout << num << " ";
}
cout << endl;
return 0;
}
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
class GfG {
public static ArrayList<Integer> findGreater(int[] arr) {
// Calculate frequency of
// each element using a hash map.
Map<Integer, Integer> freq = new HashMap<>();
for (int num : arr) {
freq.put(num, freq.getOrDefault(num, 0) + 1);
}
ArrayList<Integer> result = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
boolean found = false;
// Inner loop to find the first
// element with a greater frequency
for (int j = i + 1; j < arr.length; j++) {
if (freq.get(arr[j]) > freq.get(arr[i])) {
result.add(arr[j]);
found = true;
break;
}
}
// If no element with a greater
// frequency is found, set -1
if (!found) {
result.add(-1);
}
}
return result;
}
public static void main(String[] args) {
int[] arr = {2, 1, 1, 3, 2, 1};
ArrayList<Integer> result = findGreater(arr);
for (int num : result) {
System.out.print(num + " ");
}
System.out.println();
}
}
from collections import Counter
def findGreater(arr):
# Calculate frequency of each
# element using Counter.
freq = Counter(arr)
result = []
for i in range(len(arr)):
found = False
# Inner loop to find the first element
# with a greater frequency
for j in range(i + 1, len(arr)):
if freq[arr[j]] > freq[arr[i]]:
result.append(arr[j])
found = True
break
# If no element with a greater frequency
# is found, append -1
if not found:
result.append(-1)
return result
if __name__ == "__main__":
arr = [2, 1, 1, 3, 2, 1]
result = findGreater(arr)
print(' '.join(map(str, result)))
using System;
using System.Collections.Generic;
class GfG {
public static List<int> FindGreater(int[] arr) {
// Calculate frequency of
// each element using a dictionary
Dictionary<int, int> freq = new Dictionary<int, int>();
foreach (int num in arr) {
if (freq.ContainsKey(num)) {
freq[num]++;
} else {
freq[num] = 1;
}
}
List<int> result = new List<int>();
for (int i = 0; i < arr.Length; i++) {
bool found = false;
// Inner loop to find the first
// element with a greater frequency
for (int j = i + 1; j < arr.Length; j++) {
if (freq[arr[j]] > freq[arr[i]]) {
result.Add(arr[j]);
found = true;
break;
}
}
// If no element with a greater
// frequency is found, add -1
if (!found) {
result.Add(-1);
}
}
return result;
}
static void Main() {
int[] arr = {2, 1, 1, 3, 2, 1};
List<int> result = FindGreater(arr);
Console.WriteLine(string.Join(" ", result));
}
}
function findGreater(arr) {
// Calculate frequency of
// each element using an object.
const freq = {};
arr.forEach(num => {
freq[num] = (freq[num] || 0) + 1;
});
const result = [];
for (let i = 0; i < arr.length; i++) {
let found = false;
// Inner loop to find the first
// element with a greater frequency
for (let j = i + 1; j < arr.length; j++) {
if (freq[arr[j]] > freq[arr[i]]) {
result.push(arr[j]);
found = true;
break;
}
}
// If no element with a greater
// frequency is found, push -1
if (!found) {
result.push(-1);
}
}
return result;
}
// Driver Code
const arr = [2, 1, 1, 3, 2, 1];
const result = findGreater(arr);
console.log(result.join(' '));
Output
1 -1 -1 2 1 -1
[Efficient Approach] Frequency Counting and Stack - O(n) Time and O(n) Space
The idea is to use a frequency map to count occurrences, then apply a stack-based approach (similar to "Next Greater Element") to efficiently find the next element with a higher frequency for each position.
Step By Step Implementation:
- Count the frequency of each element using a hash map.
- Use a stack to keep indices of elements and a result array initialized with -1.
- For each element, while the stack is not empty and the current element's frequency is higher than the frequency of the element at the stack's top index, pop from the stack and set the result for that index to the current element.
- Push the current index onto the stack.
- The result array contains the next element with a higher frequency or -1 if none exists.
#include <iostream>
#include <stack>
#include <vector>
#include <map>
using namespace std;
vector<int> findGreater(vector<int>& arr) {
int n = arr.size();
map<int, int> freq;
for (auto it : arr) {
freq[it]++;
}
vector<int> res(n, -1);
stack<int> s;
for (int i = 0; i < n; i++) {
// While current frequency is
// greater than frequency at stack top
while (!s.empty() && freq[arr[i]] >
freq[arr[s.top()]]) {
res[s.top()] = arr[i];
s.pop();
}
s.push(i);
}
return res;
}
int main() {
vector<int> arr = {2, 1, 1, 3, 2, 1};
vector<int> result = findGreater(arr);
for (int x : result) {
cout << x << " ";
}
return 0;
}
import java.util.Stack;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
class GfG {
public static ArrayList<Integer>
findGreater(int[] arr) {
int n = arr.length;
Map<Integer, Integer> freq = new HashMap<>();
for (int num : arr) {
freq.put(num, freq.getOrDefault(num, 0) + 1);
}
int[] res = new int[n];
Arrays.fill(res, -1);
Stack<Integer> s = new Stack<>();
for (int i = 0; i < n; i++) {
// While current frequency is greater
// than frequency at stack top
while (!s.isEmpty() && freq.get(arr[i]) >
freq.get(arr[s.peek()])) {
res[s.pop()] = arr[i];
}
s.push(i);
}
// Convert array to ArrayList and return
ArrayList<Integer> result = new ArrayList<>();
for (int x : res) {
result.add(x);
}
return result;
}
public static void main(String[] args) {
int[] arr = {2, 1, 1, 3, 2, 1};
ArrayList<Integer> result = findGreater(arr);
for (int x : result) {
System.out.print(x + " ");
}
}
}
def findGreater(arr):
n = len(arr)
freq = {}
# Build frequency map
for num in arr:
freq[num] = freq.get(num, 0) + 1
res = [-1] * n
s = []
for i in range(n):
# While current frequency is
# greater than frequency at stack top
while s and freq[arr[i]] > freq[arr[s[-1]]]:
res[s.pop()] = arr[i]
s.append(i)
return res
if __name__ == "__main__":
arr = [2, 1, 1, 3, 2, 1]
result = findGreater(arr)
print(' '.join(map(str, result)))
using System;
using System.Collections.Generic;
class GfG {
public static List<int> findGreater(int[] arr) {
int n = arr.Length;
Dictionary<int, int> freq =
new Dictionary<int, int>();
// Build frequency map
foreach (var num in arr) {
if (freq.ContainsKey(num)) freq[num]++;
else freq[num] = 1;
}
int[] res = new int[n];
Array.Fill(res, -1);
Stack<int> s = new Stack<int>();
for (int i = 0; i < n; i++) {
// While current frequency is
// greater than frequency at stack top
while (s.Count > 0 && freq[arr[i]] >
freq[arr[s.Peek()]]) {
res[s.Pop()] = arr[i];
}
s.Push(i);
}
// Convert array to List<int> and return
List<int> result = new List<int>();
foreach (int x in res) {
result.Add(x);
}
return result;
}
static void Main() {
int[] arr = {2, 1, 1, 3, 2, 1};
List<int> result = findGreater(arr);
Console.WriteLine(string.Join(" ", result));
}
}
function findGreater(arr) {
let n = arr.length;
let freq = {};
// Build frequency map
for (let num of arr) {
freq[num] = (freq[num] || 0) + 1;
}
let res = new Array(n).fill(-1);
let s = [];
for (let i = 0; i < n; i++) {
// While current frequency is
// greater than frequency at stack top
while (s.length > 0 && freq[arr[i]] >
freq[arr[s[s.length - 1]]]) {
res[s.pop()] = arr[i];
}
s.push(i);
}
return res;
}
// Driver Code
let arr = [2, 1, 1, 3, 2, 1];
let result = findGreater(arr);
console.log(result.join(' '));
Output
1 -1 -1 2 1 -1