/**
* 362. Design Hit Counter
* Design a hit counter which counts the number of hits received in the past 5 minutes.
* Each function accepts a timestamp parameter (in seconds granularity) and you may assume that calls are
* being made to the system in chronological order (ie, the timestamp is monotonically increasing).
* You may assume that the earliest timestamp starts at 1.
* It is possible that several hits arrive roughly at the same time.
* Example:
* HitCounter counter = new HitCounter();
* // hit at timestamp 1.
* counter.hit(1);
* // hit at timestamp 2.
* counter.hit(2);
* // hit at timestamp 3.
* counter.hit(3);
* // get hits at timestamp 4, should return 3.
* counter.getHits(4);
* // hit at timestamp 300.
* counter.hit(300);
* // get hits at timestamp 300, should return 4.
* counter.getHits(300);
* // get hits at timestamp 301, should return 3.
* counter.getHits(301);
* Follow up:
* What if the number of hits per second could be very large? Does your design scale?
*/
See the solution to the problem on github here: https://github.com/zcoderz/leetcode/blob/main/src/main/java/frequent/medium/HitCounter.java
Solution is simple:
- Keep the count of times in a treemap
- For insertions, add the data to time stamp and increment count
- For retrieval
- Use headMap to get values less than and inclusive of the time stamp
- Use tailMap to filter out values less than the prior (timestamp – 5*60) threshold
- Iterate over data to calculate total count while skipping the row with key equal to prior
Here is the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /** Record a hit. @param timestamp - The current timestamp (in seconds granularity). */ void hit( int timestamp) { int count = set.getOrDefault(timestamp, 0 ); set.put(timestamp, count+ 1 ); } /** Return the number of hits in the past 5 minutes. @param timestamp - The current timestamp (in seconds granularity). */ public int getHits( int timestamp) { int prior = timestamp - ( 60 * 5 ); //search the lower and higher edges to find the count. SortedMap<Integer, Integer> less = set.headMap(timestamp, true ); SortedMap<Integer, Integer> tailMap = less.tailMap(prior); int count = 0 ; for (Map.Entry<Integer, Integer> entry : tailMap.entrySet()) { //strip out any record equal to prior value as that maybe present but shouldn't to be included if (entry.getKey().equals(prior)) continue ; count += entry.getValue(); } return count; } |