I am doing the Hacker Rank Frequency Queries question and all my test cases pass but one for Time limit exceeded. What can I do to make my program more efficient.
static List<Integer> freqQuery(List<List<Integer>> queries) {
List<Integer> freqCount = new ArrayList();
HashMap<Integer, Integer> data = new HashMap<>();
for(List q : queries){
int op = (Integer)q.get(0);
int num = (Integer)q.get(1);
switch (op){
case 1:
if(data.get(num) == null){
//Add new value to hashmap
data.put(num, 1);
}else{
data.put(num, data.get(num) + 1);
}
break;
case 2:
if(data.get(num) != null){
if(data.get(num) == 0){
//data.remove(num);
}else{
data.put(num, data.get(num) - 1);
}
}
break;
case 3:
if(data.containsValue(num)){
freqCount.add(1);
}else{
freqCount.add(0);
}
break;
}
}
return freqCount;
}
Advertisement
Answer
The time complexity
of boolean containsValue(Object value)
of class HashMap<K,V>
is O(n)
. If in case 3
, you can do a constant time look up – O(1)
, your code will be quite efficient.
According to the constraints mentioned in the problem statement:
Maximum number of queries:
1 <= q <= 10^5
Maximum possible value of x, y and z:
1 <= x, y, z <= 10^9
In order to check if any integer is present in your data structure whose frequency is exactly z in O(1)
, you can use an simple array.
If there is an element e
in your array at an index z
, then it will denote that there are e
elements in your data structure with frequency z
. The index of your array denotes frequency and the value at that index denotes the number of elements in your data structure with that frequency. You can call this array as nestedFrequency
since it stores the frequency of frequencies. The size
of the array will be 100001
. Since the maximum number of possible queries are 100000, there can be no element whose frequency is greater than 100000.
Pseudocode:
for i = 1 to queries.length
int choice = queries[i][0]
int number = queries[i][1]
switch (choice)
case 1:
Add the number in hashMap and map it to a value of 0 if not already
present.
//Obtain the previous frequency of that number in hashMap
int oldFre = hashMap.get(number)
//Update the nested frequency array
nestedFrequency[oldFre]--
nestedFrequency[oldFre+1]++
//Update the frequency of that number in hashmap
Increase the frequency of that number in hashMap
case 2:
if there is a mapping present of the given number in hashMap
//Obtain the previous frequency of that number in hashMap
int oldFre = hashMap.get(number)
//Update the nested frequency array
nestedFrequency[oldFre]--
if (oldFre-1 != 0) nestedFrequency[oldFre-1]++
//Update the frequency of that number in hashmap
if (oldFre-1 == 0) remove the mapping of that element in hashmap
else decrease its old frequency
case 3:
if number < 100001 and nestedFrequncy[number] > 0
print 1
else
print 0
I hope I have helped you. Do comment for any further problems.