views:

426

answers:

4

Can someone tell me which data structure supports insert/delete/maximum operation in O(1) ?

Thanks Ram

+2  A: 

If you are using only comparisons, you would be hard pressed to find such a data structure.

For instance you could insert n elements, get max, delete max etc and could sort numbers in O(n) time, while the theoretical lower bound is Omega(nlogn).

Moron
It's not lower bound O(n log n), there are circuits that can sort in O(n) and algorithms implementable in C that work in O(n log log n)
Dani
@Dani: Did you read the first sentence of the answer?
Moron
Thoretical lower bound is O(n) (with exponential space)
Dani
@Dani, and a non-deterministic machine? :)
Dimitris Andreou
If I only knew what it is
Dani
@Dani: First off, use Omega for lower bounds. Second, if you use exponetial space, how can the time be linear? Even initializing the exponential space will be exponential. Sorry to say this, but you seem to be talking nonsense here.
Moron
Parallelization? The amount of steps that must be done in specific order is O(n), the rest can be parallel.
Dani
A: 

A hash table might support insert/delete in O(1), no clue about maximum though. You'd probably need to keep track of it yourself somehow.

VHristov
Maximum is O(N) for a simple hash table.
KennyTM
It would be easy to amend a hashtable to keep track of the max, so I'm pretty sure this is along the right lines.
Will A
@Will: But that will make delete O(N).
KennyTM
@Will: Not really. How would you cater to deletes? What would you do if we happen to delete the maximum?
Moron
@KennyTM, @Moron very true - I engaged keyboard before brain again! :)
Will A
+5  A: 

@KennyTM's comment points out an important missing detail - insert where, and delete from where. So I am going to assume that you always want to insert and delete only from one end like a stack.

Insertion (push) and Delete (pop) are O(1).

To get Max in O(1), use an additional stack to record the current max which corresponds to the main stack.

Anurag
+1: I guess this was the "usual" interview question or homework involving two stacks / stack with two values (current, max) and insert/delete is rather push/pop.
andras
@and: Why assume this is an interview question? Ram might well be just curious and not sure how changing the problem will help in that case. I would think if the order of inserts/deletes matters, OP would have mentioned that. -1: Till OP clarifies.
Moron
@Moron: because of the "homework" tag, the "which data structure supports" part - and I have already met this question worded misleadingly. :) Of course, as you have pointed out it could be that Ram is just curious.
andras
@and: What homework tag ;-)? If you look at the edits Ram never put the homework tag. It was added by someone else.
Moron
@Moron: the fact that I have already heard the exact same question from people who boasted with their smart puzzles that they give to job applicants was a strong indication for me that it is in fact an interview question.
andras
@andras: Just because is sounds similar to some other question, I think it is incorrect to assume that it is the same. If it was what Anurag/you assumed, I would say the question would have mentioned 'stack' somewhere! From the fact that it does not, I believe the question is about finding a DataStructure which can do insert/delete arbitrary/max operation in O(1) time. Anyway... OP can always clarify.
Moron
@Moron: to clarify: I have met this question with the same exact misleading wording.A guy told me that it is more interesting to watch for reactions.Applicant type #1 - think-outside-the-box guy: since the interviewer did not mention anything else, constrains delete/insert to last element, problem solved. Applicant type #2 - regular guy: goes on to explain how it is impossible and what the lower theoretical limit is with different data structures. Applicant type #3 - clueless.I believe I would be #2 as well without hints (like delete/insert is for the last element). :)
andras
@andras: Sorry, the stack max thing has been beaten to death already, and I would not consider it "out of the box". A linked list works too, for that matter. I could interpret delete to mean delete the min always and that could be made to work too. If the interviewer is looking to mislead with such wording, I think he is an idiot. Anyway, this conversation is pointless, and OP's clarification is all we need :-)
Moron
@Moron: I guess the more one thinks about, the more one finds this answer useful. It satisfies all the requirements set forth in the question. Namely, the question did not ask for deletes in arbitrary order. :)
andras
@Moron: Yeah, I know. :) I was just answering your question as to why I think that the most probable answer is this one.
andras
@andras: Have to disagree. In your interpretation (pick your own constraints on inserts and deletes) the question kind of becomes meaningless. Anyway, pardon me if I don't respond anymore, we are just talking while all we need is OP to tell us what the interpretation is :-) Edit: Ok I see our comments crossed :-)
Moron
"Insert where, delete from where". These questions are meaningless. The stated data structure defines operations insert(x), delete(x), top(). An implementation of these is free to store the elements *anywhere it pleases*. What matters is: 1) is the implementation correct?, and 2) are the bounds of the operations O(1), as required? Btw your answer is wrong, as others pointed out.
Dimitris Andreou
"is the implementation correct?" - thanks for pointing that out. I would have never guessed that requirement. The question in its current form is **vague**. Why? Because there is such a [machine](http://stackoverflow.com/questions/2489190/gravity-sort-is-this-possible-programatically/2527873#2527873) in my backyard that only sorts spheres of varying dimensions (magnitude). Insertion and deletion are O(1). Just drop the thing and take it out. Finding the maximum is again O(1). The machine tracks which sphere hit the base first. But I suppose the OP isnt looking for something like that.
Anurag
@Anu: Don't be silly. Do you really want OP to specify a model of computation each time a question is asked? Frankly, I think there is only one _reasonable_ interpretation of this question and you don't have it. (Just check questions like these in CLR/any algorithms text and see what the intent is).
Moron
+7  A: 

This is a classical interview question, and is usually presented like this:

Devise a stack-like data structure that does push, pop and min (or max) operations in O(1) time. There are no space constraints.

The answer is, you use two stacks: the main stack, and a min (or max) stack.

So for example, after pushing 1,2,3,4,5 onto the stack, your stacks would look like this:

MAIN   MIN
+---+  +---+
| 5 |  | 1 |
| 4 |  | 1 |
| 3 |  | 1 |
| 2 |  | 1 |
| 1 |  | 1 |
+---+  +---+

However, if you were to push 5,4,3,2,1, the stacks would look like this:

MAIN   MIN
+---+  +---+
| 1 |  | 1 |
| 2 |  | 2 |
| 3 |  | 3 |
| 4 |  | 4 |
| 5 |  | 5 |
+---+  +---+

For 5,2,4,3,1 you would have:

MAIN   MIN
+---+  +---+
| 1 |  | 1 |
| 3 |  | 2 |
| 4 |  | 2 |
| 2 |  | 2 |
| 5 |  | 5 |
+---+  +---+

and so on.

You can also save some space by pushing to the min stack only when the minimum element changes, iff the items are known to be distinct.

Can Berk Güder
-1: Same answer as Anurag's and does not actually answer the question (IMO).
Moron
i went to interview for last week some folks asked me this question, i suggested priority queue. your answer seems to be correct
ram
@Ram: Sorry, I disagree that this is the correct answer. (As you yourself do not know exactly what they were asking). The interpretation of constraining either the inserts or deletes is silly, IMO. Anyway, since this is your question, you are free to do as you please :-)
Moron
You can also do the space saving even without knowing items are distinct. On pop, only pop the min stack if popped value == minStack.Peek() and (mainStack.Empty || popped != mainStack.Peek()) (after pop). It makes for a more expensive pop, but still in constant time complexity.
Jon Hanna
@Moron: Agree. I don't think push/pop is equivalent to insert/delete. I think an infinite size random access storage (aka infinite size RAM) could do the job. To store integers, just set the corresponding bit to 1. For example, to store the elements [3, 4, 7], just set the 3rd, 4th and 7th bit in the infinite storage, resulting "01001100" in the 1st byte. Use another integer to store the maximum element (7 is stored in this case). Listing all the elements in the array is O(m) [m is the max. element], but inserting (setting the bit), deleting (unsetting the bit) and finding the maximum is O(1).
Siu Ching Pong - Asuka Kenji
@Siu: When the model is not specified, I think we can assume a 'practical' RAM machine I suppose. You solution will work if the integers are bounded. The question does not mention integers, though.
Moron
@Moron: Since there is a limit on the characters in one comment, I supposed the solution for other types should be left for an exercise :). The question posted by Güder was pretty short. I don't think making no assumption at all is practical either. By the way, we can assume that the elements are of the type (or share the same superclass), or at least, comparable to each other. I treat this question as somehow similar to an "IQ Quiz" (or mind-breaker), since, as far as I know, it is impossible to construct such a data structure for "a normal computer" in a practical situation.
Siu Ching Pong - Asuka Kenji
@Moron: Here goes my answer for the "exercise": For integers that fit in one CPU register, follow the solution I posted above. For integers that don't fit in one CPU register, treat them as objects (described below). For floating point numbers, just use the bit representation as if they're integers. For objects with unique integer identifiers, use the same algorithm above, but store the whole object in the "slot" instead of setting the bit. For objects with unique identifiers which are not integers, transform them into unique integers if possible. (I don't think this should be explained.)
Siu Ching Pong - Asuka Kenji
@Moron: For objects that don't have transformable identifier, or don't have an identifier at all, use the whole object bytes (bits) as integers.
Siu Ching Pong - Asuka Kenji
@Siu: One problem I see is with duplicates. Two different bytes of the objects might be different, but they might in fact be the 'same' object. Deleting would become a problem then. Anyway, I agree with you :-)
Moron
its an acceptable answer for this question. but the question itself has no practical purpose other than confusing candidates
ram
@Ram: All I can say is that you most likely misunderstood the interviewer. Sorry if that sounds rude. Maafi. The interpretation in this answer and Anurag's is pretty ridiculous, IMO and if the interviewer was looking for that, he is an idiot. The other interpretation actually makes the question of practical use.
Moron
Turns out this question was asked before, and answered by none other than Jon Skeet. See my comment on the question. For reference, I myself was once asked this question (and got confirmation that my answer was correct) at a Google interview. Jon also works at Google, so he might have asked/have been asked this question at interviews.
Can Berk Güder
@Can: No, it is not the same. The other question _explicitly_ states to design a _stack_ with push/pop/max being O(1). Stack isn't mentioned anywhere in this question. If you look at any standard text, questions like these (which ask for a datastructure instead of explicitly specifying one) imply insert(x), delete(x) and max. Not insert on top, delete from top and max (which IMO is a ridiculous interpretation).
Moron