Can someone tell me which data structure supports insert/delete/maximum operation in O(1)?
@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.
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.
Like some have already pointed out, the question lacks some information. You don't specify were to insert/delete, nor the nature of the data we are dealing with.
Some ideas that could be useful: You say,
insert/delete/maximum operation in O(1)
note that if we can insert, delete, and find maximun in O(1), then we can use this hipotetical technique to sort in O(n), because we can insert the n elements, and then take max/delete and we get them all sorted. It's proven that no sorting algorithm based in comparisons can sort in less than O(nlogn), so we know that no comparison based aproach will work. In fact, one of the fastest known ways of doing this is the Brodal queue, but it's deletion time exceeds O(1).
Maybe the solution is something like a radix tree, were the complexity of all these operations is related to the key length as oposed to the amount of keys. This is valid only if they let you bound the key length by some other number, so you can consider it constant.
But maybe it wasn't something that generic. Another interpretation, is that the insert/delete are the ones of a classic stack. In that restricted case, you can use the double stack solutiom that Can Berk Güder gave you.
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).
The following solution uses O(1) extra memory and O(1) time for max, push and pop operations. Keep a variable max which will keep track of the current max element at any particular time. Lets utilize the fact that when max is updated, all the elements in the stack should be less than the new max element. When a push operation occurs and the new element(newElement) is greater than the current max we push the max + newElement in the stack and update max = newElement.
When we are doing a pop operation and we find that the current popped element is greater than the current max then we know that this is place where we had updated our stack to hold max+elem. So the actual element to be returned is max and max = poppedElem - max.
For eg. if we are pushing 1, 2, 3, 4, 5 the stack and max variable will look like below:
MAIN Value of MAX
+---+ +---+
| 9 | max = | 5 |
| 7 | max = | 4 |
| 5 | max = | 3 |
| 3 | max = | 2 |
| 1 | max = | 1 |
+---+ +---+
Now lets say we pop an element, we will basically pop, max element(since top > max) and update the max element to (top-max)
MAIN Value of MAX
+---+ +---+
| 7 | max = | 4 | = (9-5)
| 5 | max = | 3 |
| 3 | max = | 2 |
| 1 | max = | 1 |
+---+ +---+
Now lets say we are pushing numbers 5, 4, 3, 2, 1, the stack will look like:
MAIN Value of MAX
+---+ +---+
| 1 | max = | 5 |
| 2 | max = | 5 |
| 3 | max = | 5 |
| 4 | max = | 5 |
| 5 | max = | 5 |
+---+ +---+
When we pop, the top of stack is popped since top < max, and max remains unchanged.
Following is a pseudo code for each of the operation for better insight.
Elem max;
void Push(Elem x){
if x < max :
push(x);
else{
push(x+max);
max = x;
}
}
Elem Pop(){
Elem p = pop();
if |p| < |max|:
return p;
else{
max = p - max;
return max;
}
}
Elem Max(){
return max;
}
push and pop are normal stack operations. Hope this helps.
Below program keeps track of max elements in stack in such a way that any point of time the top pointer would give us the max in the stack : So, max would be O(1), and we can find max by max[N]
ITEM MAX
+---+ +---+
| 1 | | 1 |
| 10| | 10|
| 9 | | 10|
| 19| | 19| <--top
+---+ +---+
Java Program:
public class StackWithMax {
private int[] item;
private int N = 0;
private int[] max;
public StackWithMax(int capacity){
item = new int[capacity];//generic array creation not allowed
max = new int[capacity];
}
public void push(int item){
this.item[N++] = item;
if(max[N-1] > item) {
max[N] = max[N-1];
} else {
max[N] = item;
}
}
public void pop() {
this.item[N] = 0;
this.max[N] = 0;
N--;
}
public int findMax(){
return this.max[N];
}
public static void main(String[] args) {
StackWithMax max = new StackWithMax(10);
max.push(1);
max.push(10);
max.push(9);
max.push(19);
System.out.println(max.findMax());
max.pop();
System.out.println(max.findMax());
}
}