See this code I have written to solve this hackerrank challenge.
Essentially, at this point, I KNOW that my code is algorithmically fast enough to be acceptable for this challenge, because what I have done is EXACTLY what is discussed in the editorial section. However, the code terminates due to timeout. Therefore, I'm wondering whether theres some glaring inefficiencies in the data structures I used or if it could be a memory problem or something. Also, it is worth noting that the editorial is written in c++ and I have written my code in java
I'll describe what's going on. Queries is the list of queries to perform. countMap is a HashMap that will store how many times a given number appears in the array. freqMap is a HashMap that stores how many instances there are of a number appearing x (key) times in the array. So for example, if I add the number 5 to the array, I will add 1 to the value at key 5 in countMap. Then, if the value at key 5 in countMap is now 6, meaning that 5 occurs 6 times in the array, I will add 1 to the value at key 6 in the freqMap, since a number occurs 6 times in the array. Then, if a query happens to check if there are any numbers that appear exactly 6 times in the array, I can check directly in freqMap, and if the value at key 6 is >0, I add the number 1 to the result ArrayList. Else, I add a 0 to the result ArrayList.
static List<Integer> freqQuery(List<List<Integer>> queries) {
HashMap<Integer,Integer> countMap = new HashMap();
HashMap<Integer,Integer> freqMap = new HashMap();
List<Integer> res = new ArrayList();
for(int i = 0; i < queries.size(); i++){
List<Integer> query = queries.get(i);
Integer qType = query.get(0);
Integer qVal = query.get(1);
if(qType == 1){
Integer countVal = countMap.get(qVal);
if(countVal == null){
countVal = new Integer(0);
}
countVal += 1;
countMap.put(qVal,countVal);
Integer freqVal = freqMap.get(countVal);
if(freqVal == null){
freqVal = new Integer(0);
}
freqVal += 1;
freqMap.put(countVal,freqVal);
if ((countVal - 1) > 0) {
Integer prevFreqVal = freqMap.get(countVal - 1);
prevFreqVal -= 1;
freqMap.put((countVal -1),prevFreqVal);
}
}else if(qType == 2){
Integer countVal = countMap.get(qVal);
if(countVal != null && countVal != 0){
countVal -= 1;
countMap.put(qVal,countVal);
Integer freqVal = freqMap.get(countVal);
if(freqVal == null){
freqVal = new Integer(0);
}
freqVal += 1;
freqMap.put(countVal,freqVal);
Integer prevFreqVal = freqMap.get(countVal + 1);
prevFreqVal -= 1;
freqMap.put((countVal + 1),prevFreqVal);
}
}else if(qType == 3){
Integer freqVal = freqMap.get(qVal);
if(freqVal == null || freqVal < 1){
res.add(0);
}else{
res.add(1);
}
}
}
return res;
}
All the results are correct, but I'm getting a timeout error, indicating that my code is not fast enough. I'm lost as to why this is.
HashMap get and put operations are O(1), iterating through the queries once is obviously O(q). Adding to the end of arraylist seems to be O(n), where n is length of arraylist.