Here is an exercise (3-15) in the book “Algorithm Design Manual”.
Design a data structure that allows one to search, insert, and delete an integer X in O(1) time (i.e. , constant time, independent of the total number of integers stored). Assume that 1 ≤ X ≤ n and that there are m + n units of space available, where m is the maximum number of integers that can be in the table at any one time. (Hint: use two arrays A[1..n] and B[1..m].) You are not allowed to initialize either A or B, as that would take O(m) or O(n) operations. This means the arrays are full of random garbage to begin with, so you must be very careful.
I am not really seeking for the answer, because I don’t even understand what this exercise asks.
From the first sentence:
Design a data structure that allows one to search, insert, and delete an integer X in O(1) time
I can easily design a data structure like that. For example:
Because 1 <= X <= n, so I just have an bit vector of n slots, and let X be the index of the array, when insert, e.g., 5, then a[5] = 1; when delete, e.g., 5, then a[5] = 0; when search, e.g.,5, then I can simply return a[5], right?
I know this exercise is harder than I imagine, but what’s the key point of this question?
You are basically implementing a multiset with bounded size, both in number of elements (
#elements <= m), and valid range for elements (1 <= elementValue <= n).myCollection.search(x)–> return True if x inside, else FalsemyCollection.insert(x)–> add exactly one x to collectionmyCollection.delete(x)–> remove exactly one x from collectionConsider what happens if you try to store 5 twice, e.g.
That is why you cannot use a bit vector. But it says “units” of space, so the elaboration of your method would be to keep a tally of each element. For example you might have
[_,_,_,_,1,_,...]then[_,_,_,_,2,_,...].Why doesn’t this work however? It seems to work just fine for example if you insert 5 then delete 5… but what happens if you do
.search(5)on an uninitialized array? You are specifically told you cannot initialize it, so you have no way to tell if the value you’ll find in that piece of memorye.g. 24753actually means “there are 24753 instances of5” or if it’s garbage.NOTE: You must allow yourself
O(1)initialization space, or the problem cannot be solved. (Otherwise a.search()would not be able to distinguish the random garbage in your memory from actual data, because you could always come up with random garbage which looked like actual data.) For example you might consider having a boolean which means “I have begun using my memory” which you initialize to False, and set to True the moment you start writing to yourmwords of memory.If you’d like a full solution, you can hover over the grey block to reveal the one I came up with. It’s only a few lines of code, but the proofs are a bit longer: