Amazon Interview Question
Software Engineer / DevelopersActually what I feel using another stack is not so much impressive. Because you
cannot call GetMax() implementation will be on that stack which is not correct.
AND also holding pointer to max-node is not good because of memory.
If : Its a class ie: class CStack, then we can create a member variable 'max_value'
which holds the max value stored in the stack.and Obj.GetMax() will return the value.
My solution is same as xyz.. except that xyz has forgotten to take care of removing the max value.
For which you will need a doubly linked list for the stack, so that we can remove the maxpointer
a) change the prevptr to the maxpointer->nextptr
b) and change the top->maxpointer = top->prevptr->maxpointer.
why would u remove the max element?
question clearly says getmax() need not remove the max element. if pop removes the max element(if that is the max), next top points to current max. In the sense that at every level each node points to max upto that level.
then you solution is similar to "using a second stack to store the max". I think that solution is the correct one.
I guess this question is already posted before .. one elegant solution is to maintain 2 elements ( for each push operation that you do on the stack ) , one is the element and the other is max
lets say , you try to push 3 ,4 7 , 2 , 5 in that order
push(3) stack top has (3,3) = (elem,max)
push(4) stack top has (4,4)
push(7) stack top has (7,7)
push(2) stack top has (2,7)
push(5) stack top has (5,7)
the idea is to compare the element that you are pushing on to the top of stack with the already existing max element , and then decide the new max element .
import java.util.Stack;
public class MaxStack {
private static class Node {
int data;
int max;
}
Stack<Node> stack;
public MaxStack(){
stack = new Stack<Node>();
}
public int push (int data){
Node n = new MaxStack.Node();
n.data = data;
if (stack.empty() || stack.peek().max <= n.data) {
n.max = n.data;
} else n.max = stack.peek().max;
stack.push(n);
return data;
}
public int pop(){
return stack.pop().data;
}
public int peek(){
return stack.peek().data;
}
public int getMax(){
return stack.peek().max;
}
public boolean empty() {
return stack.empty();
}
}
Reposting with whitespaces
import java.util.Stack;
public class MaxStack {
private static class Node {
int data;
int max;
}
Stack<Node> stack;
public MaxStack(){
stack = new Stack<Node>();
}
public int push (int data){
Node n = new MaxStack.Node();
n.data = data;
if (stack.empty() || stack.peek().max <= n.data) {
n.max = n.data;
} else n.max = stack.peek().max;
stack.push(n);
return data;
}
public int pop(){
return stack.pop().data;
}
public int peek(){
return stack.peek().data;
}
public int getMax(){
return stack.peek().max;
}
public boolean empty() {
return stack.empty();
}
For GetMax, everytime when a element is pushed, top of stack should be compared with MAX ptr.
eg: 5 6 3 2 7
PUSH MAX STACK
5 5 5
6 6 5 6
3 6 5 6 3
2 6 5 6 3 2
7 7 5 6 3 2 7
I would rather suggest implementing a stack as a linked list except for the fact that the header node should have an additional reference to the node containing the max element.Since the node containing the max element need not be popped when getMax() is called having a reference to the max node will be sufficient.
Note the every push and pop operation will require comparing the node's value with that of the header node and would require updation of the header node accordingly.
I think the solution where we keep the current value and the max value of the elements below it is the best.
People here are telling that only storing the max value is enough, but that is not enough the reason being, if the max value is popped out[using a pop operation] then we need to rescan the stack to get the next max value which takes o(n) time. So best is to have each element store the current value and max value till that point.
Simple solution would be to use max heap. push and pop operations does not mean that one need to use only stack or array. The max heap can be represented using array, the root node of heap will always return max value. push and pop operations can be used to add/remove node at the end of the heap.
Each stack element will have two part
- xyz May 26, 20101.data.
2.pointer to maximum element.
Push: check if data < top()->maxpointer->data, then the new data will also point to the same max.Othersiwe its max pointer will point to itself.
Pop: No checking :)
Max: return top()->maxpointer->data.