Common Coding Interview Questions O(1) Data Structure
Open Source Your Knowledge, Become a Contributor
Technology knowledge has to be shared and made accessible for free. Join the movement.
data structure
An exercise in understanding performance characteristics of different data structures.
Implement a class with the following methods, all with
class Constant {
public:
// Insert new key with value 1, or if key is already present, increase it by 1.
void inc(const string& key);
// Decrease the value of a key by 1. If the value is already 1, remove it from the data structure.
void dec(const string& key);
// Return one of the keys with maximum value. Return "" if datastructure is empty.
string getMaxKey() const;
// Return one of the keys with minimum value. Return "" if datastructure is empty.
string getMinKey() const;
};
In this article, we will go through the deconstruction of this problem and build up the solution step by step.
Trivial O ( n ) "solution"
Let's establish some baseline of what we can definitely do (ignoring
Fetching the maximum and minimum out of an unsorted sequence requires
Increasing and decreasing the value for a key can be done in
This solution is obviously extremely inefficient. We could improve it drastically by simply caching the result of min and max and only updating it when needed. However that wouldn't give us the desired
Solving the maximum in O ( 1 )
Our previous trivial implementation would work even if the values for the keys could change arbitrarily. Can we exploit the fact that a key can only change by one?
Let's have a look at what can happen to the maximum if we increase or decrease the value for a key.
- if the key was not the maximum, the maximum will not change
- increasing a maximum key will increase the maximum
- decreasing a maximum key can have two results:
- if this was the only key at the value, the maximum decreases
- if there are other keys with the value, the maximum does not change
Looking at this, the only information we are missing is how many keys are at a given value. We can maintain this information in
Solving minimum in O ( 1 )
At first glance, we might be able to use the same approach for minimum. That will unfortunately not work. Maximum always changes smoothly, at most by one. Minimum can however change by an arbitrary amount if the minimum key has the value
The pathological example would be to have the following keys in our datastructure:
{ a: 1, b: 2, c: 3, d: 4, ....}
If we always decrement the minimum key until it drops out of the datastructure, we will need to repeatedly determine the 2nd lowest key.
The only way to do this in
Keeping the keys sorted
Let's step back and think about what operations we actually need to do in
- when incrementing a key that is not yet present in our datastructure, we need to insert the key at the front or back of sorted sequence
- when decrementing a key that has a value of 1, we need to remove the key from (the back or the front of) the sorted sequence
So, we need
Let's have a look at what can happen to a key if it's not in one of the already mentioned corner cases.
- if we are increasing or decreasing a key and there are no other keys at either the old and the new value, we don't change the keys position in the sorted sequence
- if we are increasing or decreasing a key and there are other keys at the old value but no other keys at the new value, we will need to insert a new element into the sequence one position away from the keys previous value
- if we are increasing or decreasing a key and there are no other keys at the old value, but there are keys at the new value, we will need to remove an element from the sequence, from the keys previous value
- if there are other keys at both the old and new values, the sequence will not change, however we need to move the key from one element of the sequence to another
So, we need the following operations in
- local removals (remove element before or after a given element)
- local inserts (add element before or after a given element)
- stable iterators, so we can jump from a key to it's position in the sorted sequence
Yes, the datastructure we want is actually the rarely used linked list.
And that's it. All the operations now run in
Previous: Top
Next: Palindromes
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. Šimon Tóth 2020 (kontakt@simontoth.cz)