Next Greater Frequency Element

Given an array, for each element find the value of nearest element to the right which is having frequency greater than as that of current element. If there does not exist an answer for a position, then make the value ‘-1’.

Examples:

Input : a[] = [1, 1, 2, 3, 4, 2, 1] 
Output : [-1, -1, 1, 2, 2, 1, -1]
Explanation:
Given array a[] = [1, 1, 2, 3, 4, 2, 1] 
Frequency of each element is: 3, 3, 2, 1, 1, 2, 3
Lets calls Next Greater Frequency element as NGF
1. For element a[0] = 1 which has a frequency = 3,
   As it has frequency of 3 and no other next element 
   has frequency more than 3 so  '-1'
2. For element a[1] = 1 it will be -1 same logic 
   like a[0]
3. For element a[2] = 2 which has frequency = 2,
   NGF element is 1 at position = 6  with frequency 
   of 3 > 2
4. For element a[3] = 3 which has frequency = 1,
   NGF element is 2 at position = 5 with frequency 
   of 2 > 1
5. For element a[4] = 4 which has frequency = 1,
   NGF element is 2 at position = 5 with frequency 
   of 2 > 1
6. For element a[5] = 2 which has frequency = 2,
   NGF element is 1 at position = 6 with frequency
   of 3 > 2
7. For element a[6] = 1 there is no element to its 
   right, hence -1 

Input : a[] = [1, 1, 1, 2, 2, 2, 2, 11, 3, 3]
Output : [2, 2, 2, -1, -1, -1, -1, 3, -1, -1]

Naive approach:
A simple hashing technique is to use values as index is be used to store frequency of each element. Create a list suppose to store frequency of each number in the array. (Single traversal is required). Now use two loops.
The outer loop picks all the elements one by one.
The inner loop looks for the first element whose frequency is greater than the frequency of current element.
If a greater frequency element is found then that element is printed, otherwise -1 is printed.
Time complexity : O(n*n)

Efficient approach:
We can use hashing and stack data structure to efficiently solve for many cases. A simple hashing technique is to use values as index and frequency of each element as value. We use stack data structure to store position of elements in the array.

1) Create a list to use values as index to store frequency of each element.
2) Push the position of first element to stack.
3) Pick rest of the position of elements one by one and follow following steps in loop.
…….a) Mark the position of current element as ‘i’ .
……. b) If the frequency of the element which is pointed by the top of stack is greater than frequency of the current element, push the current position i to the stack
……. c) If the frequency of the element which is pointed by the top of stack is less than frequency of the current element and the stack is not empty then follow these steps:
…….i) continue popping the stack
…….ii) if the condition in step c fails then push the current position i to the stack
4) After the loop in step 3 is over, pop all the elements from stack and print -1 as next greater frequency element for them does not exist.

Time complexity is O(n).

Below is the implementation of the above problem.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program of Next Greater Frequency Element
#include <stack>
#include <iostream>
#include <stdio.h>
  
using namespace std;
  
/*NFG function to find the next greater frequency
element for each element in the array*/
void NFG(int a[], int n, int freq[])
{
  
    // stack data structure to store the position 
    // of array element 
    stack<int> s; 
    s.push(0);
      
    // res to store the value of next greater 
    // frequency element for each element
    int res[n] = {0};
    for (int i = 1; i < n; i++)
    {
        /* If the frequency of the element which is 
            pointed by the top of stack is greater 
            than frequency of the current element
            then push the current position i in stack*/
  
        if (freq[a[s.top()]] > freq[a[i]])
            s.push(i);
        else
        {
            /*If the frequency of the element which 
            is pointed by the top of stack is less 
            than frequency of the current element, then 
            pop the stack and continuing popping until 
            the above condition is true while the stack
            is not empty*/
  
            while (freq[a[s.top()]] < freq[a[i]] && !s.empty())
            {
  
                res[s.top()] = a[i];
                s.pop();
            }
            //  now push the current element
            s.push(i);
        }
    }
  
    while (!s.empty())
    {
        res[s.top()] = -1;
        s.pop();
    }
    for (int i = 0; i < n; i++)
    {
        // Print the res list containing next 
        // greater frequency element
        cout << res[i] << " ";
    }
}
  
//Driver code
int main()
{
  
    int a[] = {1, 1, 2, 3, 4, 2, 1};
    int len = 7;
    int max = INT16_MAX;
    for (int i = 0; i < len; i++)
    {
        //Getting the max element of the array
        if (a[i] > max) 
        {
            max = a[i];
        }
    }
    int freq[max + 1] = {0};
      
    //Calculating frequency of each element
    for (int i = 0; i < len; i++) 
    {
        freq[a[i]]++;
    }
  
    NFG(a, len, freq);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program of Next Greater Frequency Element
import java.util.*;
  
class GFG
{
  
/*NFG function to find the next greater frequency
element for each element in the array*/
static void NFG(int a[], int n, int freq[])
{
  
    // stack data structure to store the position 
    // of array element 
    Stack<Integer> s = new Stack<Integer>(); 
    s.push(0);
      
    // res to store the value of next greater 
    // frequency element for each element
    int res[] = new int[n];
    for(int i = 0; i < n; i++)
    res[i] = 0;
      
    for (int i = 1; i < n; i++)
    {
        /* If the frequency of the element which is 
            pointed by the top of stack is greater 
            than frequency of the current element
            then push the current position i in stack*/
  
        if (freq[a[s.peek()]] > freq[a[i]])
            s.push(i);
        else
        {
            /*If the frequency of the element which 
            is pointed by the top of stack is less 
            than frequency of the current element, then 
            pop the stack and continuing popping until 
            the above condition is true while the stack
            is not empty*/
  
            while (freq[a[s.peek()]] < freq[a[i]] && s.size()>0)
            {
                res[s.peek()] = a[i];
                s.pop();
            }
              
            // now push the current element
            s.push(i);
        }
    }
  
    while (s.size() > 0)
    {
        res[s.peek()] = -1;
        s.pop();
    }
      
    for (int i = 0; i < n; i++)
    {
        // Print the res list containing next 
        // greater frequency element
            System.out.print( res[i] + " ");
    }
}
  
//Driver code
public static void main(String args[])
{
  
    int a[] = {1, 1, 2, 3, 4, 2, 1};
    int len = 7;
    int max = Integer.MIN_VALUE;
    for (int i = 0; i < len; i++)
    {
        //Getting the max element of the array
        if (a[i] > max) 
        {
            max = a[i];
        }
    }
    int freq[] = new int[max + 1];
      
    for (int i = 0; i < max + 1; i++)
    freq[i] = 0;
      
    //Calculating frequency of each element
    for (int i = 0; i < len; i++) 
    {
        freq[a[i]]++;
    }
  
    NFG(a, len, freq);
}
}
  
// This code is contributed by Arnab Kundu

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

'''NFG function to find the next greater frequency
   element for each element in the array'''
def NFG(a, n):
      
    if (n <= 0):
        print("List empty")
        return []
  
    # stack data structure to store the position 
    # of array element 
    stack = [0]*n
  
    # freq is a dictionary which maintains the 
    # frequency of each element
    freq = {}
    for i in a:
        freq[a[i]] = 0
    for i in a:
        freq[a[i]] += 1
  
    # res to store the value of next greater 
    # frequency element for each element
    res = [0]*n
  
    # initialize top of stack to -1
    top = -1
  
    # push the first position of array in the stack
    top += 1
    stack[top] = 0
      
    # now iterate for the rest of elements
    for i in range(1, n):
  
        ''' If the frequency of the element which is 
            pointed by the top of stack is greater 
            than frequency of the current element
            then push the current position i in stack'''            
        if (freq[a[stack[top]]] > freq[a[i]]):
            top += 1
            stack[top] = i
  
        else
            ''' If the frequency of the element which 
            is pointed by the top of stack is less 
            than frequency of the current element, then 
            pop the stack and continuing popping until 
            the above condition is true while the stack
            is not empty'''
              
            while (top>-1 and freq[a[stack[top]]] < freq[a[i]]):
                res[stack[top]] = a[i]
                top -= 1
  
            # now push the current element
            top+=1
            stack[top] = i
              
    '''After iterating over the loop, the remaining
    position of elements in stack do not have the 
    next greater element, so print -1 for them'''        
    while (top > -1):
        res[stack[top]] = -1
        top -= 1
  
    # return the res list containing next 
    # greater frequency element
    return res
  
# Driver program to test the function
print(NFG([1,1,2,3,4,2,1],7))

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program of Next Greater Frequency Element
using System;
using System.Collections;
  
class GFG
{
  
/*NFG function to find the 
next greater frequency
element for each element 
in the array*/
static void NFG(int []a, int n, int []freq)
{
  
    // stack data structure to store  
    // the position of array element 
    Stack s = new Stack(); 
    s.Push(0);
      
    // res to store the value of next greater 
    // frequency element for each element
    int []res = new int[n];
    for(int i = 0; i < n; i++)
    res[i] = 0;
      
    for (int i = 1; i < n; i++)
    {
        /* If the frequency of the element which is 
            pointed by the top of stack is greater 
            than frequency of the current element
            then Push the current position i in stack*/
  
        if (freq[a[(int)s.Peek()]] > freq[a[i]])
            s.Push(i);
        else
        {
            /*If the frequency of the element which 
            is pointed by the top of stack is less 
            than frequency of the current element, then 
            Pop the stack and continuing Popping until 
            the above condition is true while the stack
            is not empty*/
  
            while (freq[a[(int)(int)s.Peek()]] < freq[a[i]] &&
                                                    s.Count>0)
            {
                res[(int)s.Peek()] = a[i];
                s.Pop();
            }
              
            // now Push the current element
            s.Push(i);
        }
    }
  
    while (s.Count > 0)
    {
        res[(int)s.Peek()] = -1;
        s.Pop();
    }
      
    for (int i = 0; i < n; i++)
    {
          
        // Print the res list containing next 
        // greater frequency element
        Console.Write( res[i] + " ");
    }
}
  
// Driver code
public static void Main(String []args)
{
  
    int []a = {1, 1, 2, 3, 4, 2, 1};
    int len = 7;
    int max = int.MinValue;
    for (int i = 0; i < len; i++)
    {
        // Getting the max element of the array
        if (a[i] > max) 
        {
            max = a[i];
        }
    }
    int []freq = new int[max + 1];
      
    for (int i = 0; i < max + 1; i++)
        freq[i] = 0;
      
    // Calculating frequency of each element
    for (int i = 0; i < len; i++) 
    {
        freq[a[i]]++;
    }
    NFG(a, len, freq);
}
}
  
// This code is contributed by Arnab Kundu

chevron_right



Output:

[-1, -1, 1, 2, 2, 1, -1]

This article is contributed by Sruti Rai . Thank you Koustav for your valuable support. 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 write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up



Article Tags :
Practice Tags :


13


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.