Design a stack which can give maximum frequency element
Given N elements and the task is to implement a stack which removes and returns the maximum frequency element on every pop operation. If there’s a tie in the frequency then the topmost highest frequency element will be returned.
Examples:
Input:
push(4) 8
push(6) 6
push(7) 7
push(6) 6
push(8); 4
Output:
pop() -> returns 6, as 6 is the most frequent (frequency of 6 = 2 ).
pop() -> returns 8 (6 also has the highest frequency but it is not the topmost)
Approach: Maintaining two HashMap, one is frequency HashMap which maps elements to their frequencies and other is setMap which maps all the element with same frequency in one group (Stack).
FrequencyStack has 2 functions:
- push(int x): map the element (x) with frequency HashMap and update the maxfreq variable ( i.e. holds the maximum frequency till now ). setMap maintains a stack which contains all the elements with same frequency.
- pop(): First get the maxfreq element from setMap and then decrement the frequency of the popped element. After popping, if the stack becomes empty then decrement the maxfreq.
Below is the implementation of the above approach:
C++
#include<bits/stdc++.h>
using namespace std;
unordered_map< int , int > freqMap;
unordered_map< int , stack< int > > setMap;
int maxfreq = 0;
void push( int x)
{
int freq = freqMap[x] + 1;
freqMap[x]= freq;
if (freq > maxfreq)
maxfreq = freq;
setMap[freq].push(x);
}
int pop()
{
int top = setMap[maxfreq].top();
setMap[maxfreq].pop();
freqMap[top]--;
if (setMap[maxfreq].size() == 0)
maxfreq--;
return top;
}
int main()
{
push(4);
push(6);
push(7);
push(6);
push(8);
cout << (pop()) << "\n" ;
cout << (pop());
return 0;
}
|
Java
import java.util.*;
public class freqStack {
static Map<Integer, Integer> freqMap = new HashMap<>();
static Map<Integer, Stack<Integer> > setMap = new HashMap<>();
static int maxfreq = 0 ;
public static void push( int x)
{
int freq = freqMap.getOrDefault(x, 0 ) + 1 ;
freqMap.put(x, freq);
if (freq > maxfreq)
maxfreq = freq;
setMap.computeIfAbsent(freq, z -> new Stack()).push(x);
}
public static int pop()
{
int top = setMap.get(maxfreq).pop();
freqMap.put(top, freqMap.get(top) - 1 );
if (setMap.get(maxfreq).size() == 0 )
maxfreq--;
return top;
}
public static void main(String[] args)
{
push( 4 );
push( 6 );
push( 7 );
push( 6 );
push( 8 );
System.out.println(pop());
System.out.println(pop());
}
}
|
Python3
freqMap = {};
setMap = {};
maxfreq = 0 ;
def push(x) :
global maxfreq;
if x not in freqMap :
freqMap[x] = 0
freq = freqMap[x] + 1 ;
freqMap[x] = freq
if (freq > maxfreq) :
maxfreq = freq
if freq not in setMap :
setMap[freq] = []
setMap[freq].append(x);
def pop() :
global maxfreq
top = setMap[maxfreq][ - 1 ];
setMap[maxfreq].pop();
freqMap[top] - = 1 ;
if ( len (setMap[maxfreq]) = = 0 ) :
maxfreq - = 1 ;
return top;
if __name__ = = "__main__" :
push( 4 );
push( 6 );
push( 7 );
push( 6 );
push( 8 );
print (pop()) ;
print (pop());
|
C#
using System;
using System.Collections.Generic;
class GFG {
static Dictionary< int , int > freqMap = new Dictionary< int , int >();
static Dictionary< int , Stack< int >> setMap = new Dictionary< int , Stack< int >>();
static int maxfreq = 0;
static void push( int x)
{
int freq = 1;
if (freqMap.ContainsKey(x))
{
freq = freq + freqMap[x];
}
freqMap[x] = freq;
if (freq > maxfreq)
maxfreq = freq;
if (!setMap.ContainsKey(freq))
{
setMap[freq] = new Stack< int >();
}
setMap[freq].Push(x);
}
static int pop()
{
int top = setMap[maxfreq].Peek();
setMap[maxfreq].Pop();
freqMap[top] = freqMap[top] - 1;
if (setMap[maxfreq].Count == 0)
maxfreq--;
return top;
}
static void Main() {
push(4);
push(6);
push(7);
push(6);
push(8);
Console.WriteLine(pop()) ;
Console.WriteLine(pop());
}
}
|
Javascript
<script>
var freqMap = new Map();
var setMap = new Map();
var maxfreq = 0;
function push(x)
{
if (!freqMap.has(x))
freqMap.set(x, 1)
else
freqMap.set(x, freqMap.get(x)+1)
var freq = freqMap.get(x)
freqMap.set(x, freq);
if (freq > maxfreq)
maxfreq = freq;
if (!setMap.has(freq))
{
setMap.set(freq, [x])
}
else
{
var tmp = setMap.get(freq);
tmp.push(x);
setMap.set(freq, tmp);
}
}
function pop()
{
var tmp = setMap.get(maxfreq);
var top = tmp[tmp.length-1];
tmp.pop();
setMap.set(maxfreq, tmp);
if (freqMap.has(top))
freqMap.set(top, freqMap.get(top)-1)
if (setMap.get(maxfreq).length == 0)
maxfreq--;
return top;
}
push(4);
push(6);
push(7);
push(6);
push(8);
document.write( (pop()) + "<br>" );
document.write( (pop()));
</script>
|
Time Complexity: O(1) on average
Auxiliary Space: O(N)
The above approach can be implemented using a priority queue as well
Note: max heap-based ordering is decided by frequency and then by count, all this is implicitly done by C++
C++
#include <bits/stdc++.h>
using namespace std;
priority_queue<pair< int , pair< int , int > > > q;
unordered_map< int , int > freq;
int pos = 0;
void push( int x)
{
q.emplace(++freq[x], make_pair(++pos, x));
}
int pop()
{
auto val = q.top();
q.pop();
int x = val.second.second;
freq[x]--;
return x;
}
int main()
{
push(4);
push(6);
push(7);
push(6);
push(8);
cout << (pop()) << "\n" ;
cout << (pop());
return 0;
}
|
Java
import java.util.PriorityQueue;
import java.util.HashMap;
public class Main {
static PriorityQueue< int []> q = new PriorityQueue<>(
(a, b) -> {
if (a[ 0 ] != b[ 0 ]) {
return Integer.compare(a[ 0 ], b[ 0 ]);
}
if (a[ 1 ] != b[ 1 ]) {
return Integer.compare(a[ 1 ], b[ 1 ]);
}
return Integer.compare(a[ 2 ], b[ 2 ]);
}
);
static HashMap<Integer, Integer> freq = new HashMap<>();
static int pos = 0 ;
static void push( int x) {
q.offer( new int []{-freq.getOrDefault(x, 0 ), -pos, x});
freq.put(x, freq.getOrDefault(x, 0 ) + 1 );
pos++;
}
static int pop() {
int [] val = q.poll();
int x = val[ 2 ];
freq.put(x, freq.get(x) - 1 );
return x;
}
public static void main(String[] args) {
push( 4 );
push( 6 );
push( 7 );
push( 6 );
push( 8 );
System.out.println(pop());
System.out.println(pop());
}
}
|
Python3
import heapq
from collections import defaultdict
q = []
freq = defaultdict( int )
pos = 0
def push(x):
global pos
heapq.heappush(q, ( - freq[x], - pos, x))
freq[x] + = 1
pos + = 1
def pop():
x = heapq.heappop(q)[ 2 ]
freq[x] - = 1
return x
push( 4 )
push( 6 )
push( 7 )
push( 6 )
push( 8 )
print (pop())
print (pop())
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG
{
static SortedDictionary< int , Tuple< int , int >> q =
new SortedDictionary< int , Tuple< int , int >>();
static Dictionary< int , int > freq = new Dictionary< int , int >();
static int pos = 0;
static void Push( int x)
{
if (!freq.ContainsKey(x))
freq[x] = 0;
freq[x]++;
q[-freq[x]] = Tuple.Create(++pos, x);
}
static int Pop()
{
var val = q.First();
q.Remove(val.Key);
int x = val.Value.Item2;
freq[x]--;
if (freq[x] == 0)
freq.Remove(x);
return x;
}
static void Main()
{
Push(4);
Push(6);
Push(7);
Push(6);
Push(8);
Console.WriteLine(Pop());
Console.WriteLine(Pop());
}
}
|
Javascript
let freq = {};
let arr = [];
let pos = 0;
function push(x) {
if (freq[x] === undefined) freq[x] = 0;
freq[x]++;
arr.push([freq[x], ++pos, x]);
}
function pop() {
let maxIdx = -1;
let maxVal = -1;
for (let i = 0; i < arr.length; i++) {
let [freq, idx, val] = arr[i];
if (freq > maxVal || (freq == maxVal && idx > maxIdx)) {
maxIdx = idx;
maxVal = freq;
}
}
let idx = -1;
for (let i = 0; i < arr.length; i++) {
if (arr[i][1] == maxIdx) {
idx = i;
break ;
}
}
let [freq, pos, x] = arr[idx];
freq--;
if (freq == 0) delete freq[x];
else freq[x] = freq;
arr.splice(idx, 1);
return x;
}
push(4);
push(6);
push(7);
push(6);
push(8);
console.log(pop());
console.log(pop());
|
Time Complexity: O(1) on average
Auxiliary Space: O(N)
Last Updated :
02 Oct, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...