Skip to content

432. All Oone Data Structure

Difficulty: Hard

LeetCode Problem View on GitHub


432. All O`one Data Structure

Hard


Design a data structure to store the strings' count with the ability to return the strings with minimum and maximum counts.

Implement the AllOne class:

  • AllOne() Initializes the object of the data structure.
  • inc(String key) Increments the count of the string key by 1. If key does not exist in the data structure, insert it with count 1.
  • dec(String key) Decrements the count of the string key by 1. If the count of key is 0 after the decrement, remove it from the data structure. It is guaranteed that key exists in the data structure before the decrement.
  • getMaxKey() Returns one of the keys with the maximal count. If no element exists, return an empty string "".
  • getMinKey() Returns one of the keys with the minimum count. If no element exists, return an empty string "".

Note that each function must run in O(1) average time complexity.

 

Example 1:

Input
["AllOne", "inc", "inc", "getMaxKey", "getMinKey", "inc", "getMaxKey", "getMinKey"]
[[], ["hello"], ["hello"], [], [], ["leet"], [], []]
Output
[null, null, null, "hello", "hello", null, "hello", "leet"]

Explanation
AllOne allOne = new AllOne();
allOne.inc("hello");
allOne.inc("hello");
allOne.getMaxKey(); // return "hello"
allOne.getMinKey(); // return "hello"
allOne.inc("leet");
allOne.getMaxKey(); // return "hello"
allOne.getMinKey(); // return "leet"

 

Constraints:

  • 1 <= key.length <= 10
  • key consists of lowercase English letters.
  • It is guaranteed that for each call to dec, key is existing in the data structure.
  • At most 5 * 104 calls will be made to inc, dec, getMaxKey, and getMinKey.

Solution

import java.util.*;
class AllOne {
    private HashMap<String, Integer> map;
    private TreeMap<Integer, HashSet<String>> freqMap;
    public AllOne() {
        map = new HashMap<>();
        freqMap = new TreeMap<>();
    }
    public void inc(String key) {
        if (map.containsKey(key)) {
            int freq = map.get(key);
            map.put(key, freq + 1);
            freqMap.get(freq).remove(key);
            if (freqMap.get(freq).isEmpty()) freqMap.remove(freq);
            freqMap.computeIfAbsent(freq + 1, k -> new HashSet<>()).add(key);
        } 
        else {
            map.put(key, 1);
            freqMap.computeIfAbsent(1, k -> new HashSet<>()).add(key);
        }
    }
    public void dec(String key) {
        if (!map.containsKey(key)) return;
        int freq = map.get(key);
        if (freq == 1) {
            map.remove(key);
            freqMap.get(1).remove(key);
            if (freqMap.get(1).isEmpty()) freqMap.remove(1);
        } 
        else {
            map.put(key, freq - 1);
            freqMap.get(freq).remove(key);
            if (freqMap.get(freq).isEmpty()) {
                freqMap.remove(freq);
            }
            freqMap.computeIfAbsent(freq - 1, k -> new HashSet<>()).add(key);
        }
    }
    public String getMaxKey() {
        if (freqMap.isEmpty()) return "";
        return freqMap.lastEntry().getValue().iterator().next();
    }
    public String getMinKey() {
        if (freqMap.isEmpty()) return "";
        return freqMap.firstEntry().getValue().iterator().next();
    }
}

/**
 * Your AllOne object will be instantiated and called as such:
 * AllOne obj = new AllOne();
 * obj.inc(key);
 * obj.dec(key);
 * String param_3 = obj.getMaxKey();
 * String param_4 = obj.getMinKey();
 */

Complexity Analysis

  • Time Complexity: O(?)
  • Space Complexity: O(?)

Approach

Detailed explanation of the approach will be added here