LeetCode Solutions
432. All O`one Data Structure
Time: $O(1)$ Space: $O(n)$
class AllOne {
public:
void inc(string key) {
const auto it = keyToIterator.find(key);
// doesn't find the key
if (it == cend(keyToIterator)) {
if (l.empty() || l.front().value > 1)
l.push_front({1, {key}});
else
l.front().keys.insert(key);
keyToIterator[key] = begin(l);
return;
}
const auto lit = it->second; // List iterator
auto nit = next(lit); // Next iterator
if (nit == end(l) || nit->value > lit->value + 1)
nit = l.insert(nit, {lit->value + 1, {key}});
else // Nit->value == lit->value + 1
nit->keys.insert(key);
keyToIterator[key] = nit; // Reset the mapping
// Remove the key in keys set
lit->keys.erase(key);
if (lit->keys.empty())
l.erase(lit);
}
void dec(string key) {
const auto it = keyToIterator.find(key);
// doens't find the key
if (it == cend(keyToIterator))
return;
const auto lit = it->second; // List iterator
if (lit->value == 1) { // No need to find prev iterator in this case
keyToIterator.erase(key);
} else {
auto pit = prev(lit); // Prev iterator
if (lit == begin(l) || pit->value < lit->value - 1)
pit = l.insert(lit, {lit->value - 1, {key}});
else // Pit->value == lit-value - 1
pit->keys.insert(key);
keyToIterator[key] = pit; // Reset the mapping
}
// Remove the key in keys set
lit->keys.erase(key);
if (lit->keys.empty())
l.erase(lit);
}
string getMaxKey() {
return l.empty() ? "" : *cbegin(l.back().keys);
}
string getMinKey() {
return l.empty() ? "" : *cbegin(l.front().keys);
}
private:
struct Node {
int value;
unordered_set<string> keys;
};
list<Node> l;
unordered_map<string, list<Node>::iterator> keyToIterator;
};