Microsoft unknown Interview Question
Software Engineer / DevelopersBasically you just need another stack S for storing the minimums. S.top() gives you the current min. When inserting a new item, call S.push(min(S.top(), item)). When popping an item, you just call S.pop().
It is impossible because the following: as we know, sort n numbers needs at least O(nlogn) time, if all three operations can be done in O(1) time, then we can sort in O(n) time, which is a contradiction.
oops! you gave a proof as well..
Its possible with extra space (extra stack in this case)
If we just keep a track of the new elements that are being pushed into the stack and comparing it with the existing min value , ( and hence updating as necessary ) , we can complete the task in O(1) time . And as for the push and pop things , they require O (1) in the first place , so no hassle there .
From what I got from the question
Push and pop in stack always take O(1) time but to find minimum in the stack it will take O(n) time in the worst case...
So I think its not possible to find min in O(1) time untill the stack is sorted in decreasing order...
This can be done by tweaking push(). While inssrting just check whether previous number is greater than the one which is being inserted.
This way Stack will be sorted and min is done in O(1) time.
He doesnt mean 'tweaking', he means to keep track of the min as we push. lifo would still be accomplished.
But you can not find and set the next minimum in O(1) when current minimum is popped. Thats where the problem arises.
I do second Sayak.
Basically all_ele_stack shall push all elements into it. Whereas min_ele_stack shall only push only the "running minimum" elements.
Push
-----
all_ele_stack.push(newElement)
if (newElement < min_ele_stack.peep())
min_ele_stack.push(newElement)
Pop
---
data = all_ele_stack.pop();
if (data == min_ele_stack.peep())
min_ele_stack.pop()
return data;
Min
---
return min_ele_stack.peep();
So it solves the problem with extra space complexity of O(n).
It assumes no duplication of the input data.
class LinkStack
{
static void Main(string[] args)
{
LinkStackX theStack = new LinkStackX(); //make stack
theStack.push(1, 20); //push items
theStack.push(2, 40);
theStack.displayStack(); //display stack (40, 20)
theStack.push(3, 60); //push items
theStack.push(4, 80);
theStack.displayStack(); //display (80, 60, 40, 20,)
theStack.pop(); //pop items (80, 60)
theStack.pop();
theStack.displayStack(); //display stack (40, 20)
}
class LinkStackX
{
private LinkedListX.LinkListX_ pList; //pointer to linked list
public LinkStackX() //constructor
{
pList = new LinkedListX.LinkListX_();
} //make a linked list
//--------------------------------------------------------------
public void push(int id, double j) //put item on top of stack
{
pList.insertFirst(id, j);
}
//--------------------------------------------------------------
public double pop() //take item from top of stack
{
return pList.removeFirst();
}
//--------------------------------------------------------------
public bool isEmpty() //true if stack is empty
{
return (pList.isEmpty());
}
//--------------------------------------------------------------
public void displayStack()
{
Console.WriteLine("Stack (top-->bottom): ");
pList.displayList();
}
}
}
class LinkedListX
{
public class Link
{
public int iData; //data item
public double dData; //data item
public Link pNext; //ptr to next link in list
//-------------------------------------------------------------
public Link(int id, double dd)
{
iData = id;
dData = dd;
pNext = null;
}
//-------------------------------------------------------------
public void displayLink() //display ourself {22, 2.99}
{
Console.WriteLine("iData = " + dData);
}
//-------------------------------------------------------------
}
public class LinkListX_
{
private Link pFirst; //ptr to first link on list
public LinkListX_() //constructor
{
pFirst = null;
} //(no links on list yet)
//-------------------------------------------------------------
public bool isEmpty() //true if list is empty
{
return pFirst == null;
}
//-------------------------------------------------------------
//insert at start of list
public void insertFirst(int id, double dd)
{ //make new link
Link pNewLink = new Link(id, dd);
pNewLink.pNext = pFirst; //newLink-->old first
pFirst = pNewLink; //first-->newLink
}
//-------------------------------------------------------------
public Link getFirst() //return first link
{
return pFirst;
}
//-------------------------------------------------------------
public double removeFirst() //delete first link
{ //(assumes list not empty)
Link pTemp = pFirst; //save first
pFirst = pFirst.pNext; //unlink it: first-->old next
double key = pTemp.dData;
pTemp = null; //delete old first
return key;
}
//-------------------------------------------------------------
public Link find(int key) //find link with given key
{ //(assumes non-empty list)
Link pCurrent = pFirst; //start at ‘first’
while (pCurrent.pNext != null &&
pCurrent.iData != key) //while no match,
{
pCurrent = pCurrent.pNext; //go to next link
}
return pCurrent; //found it
}
//-------------------------------------------------------------
public bool remove(int key) //remove link with given key
{ //(assumes non-empty list)
Link pCurrent = pFirst; //search for link
Link pPrevious = pFirst;
while (pCurrent.pNext != null &&
pCurrent.iData != key)
{
pPrevious = pCurrent; //go to next link
pCurrent = pCurrent.pNext;
} //found it
if (pCurrent == pFirst) //if first link,
pFirst = pFirst.pNext; //change first
else //otherwise,
pPrevious.pNext = pCurrent.pNext; //bypass it
pCurrent = null; //delete link
return true; //successful removal
}
//-------------------------------------------------------------
public void displayList()
{
Console.WriteLine("List (first-->last): ");
Link pCurrent = pFirst; //start at beginning of list
while (pCurrent != null) //until end of list,
{
pCurrent.displayLink(); //print data
pCurrent = pCurrent.pNext; //move to next link
}
}
}
}
Easy enough. Use a stack subclass, with an inner stack just for tracking min values.
When pushing, peek into the min stack and compare. If it's less than the min, push the min stack.
When popping, compare to the top of the min stack, and pop the min stack if it's the same object.
little modification. while pushing if the new value is LESS THAN EQUAL TO peek value then push in the min stack.
I think you should also track the pushing into some sort of "0;1" array: 0 - push was in the min stack; 1 - push was on the other stack.
So, if you have something like: 00111101011000 => Pop() = pop from min 3 times, from other 2 times, 1 time from min stack, etc.
I don't get it. What if the new number /isn't/ the new min? Now you have to find /how/ 'min' it is, ie you have to do a lg(n) binary search of the min stack to find where it should go.
If instead you don't do anything with the min stack, but instead just throw the 'not-min' value away, well, a few popped items later, you don't have a true stack of mins anymore; maybe 3 down is where that 'not-min' should have gone, and instead you've got the 4th down, which is > the 3rd min would have been.
However, I can't think of an O(1) solution.
Since you're working with a stack, there's no problem. The only way for an item to get removed from the stack is to pop it from the top.
We don't need to know how 'min' a value is if it isn't the minimum. Why? Because it's a stack! You'll need to pop that 'not min' value BEFORE you can pop the current min value.
Simple example: Push 4, 5
1. 4 is pushed. Since there is no min, 4 is pushed on the min stack.
2. 5 is pushed. Since 5 > 4 (min), we don't push 5 on the min stack.
5 CANNOT be the min until 4 is popped. But 4 can't be popped until 5 is popped first. And that would just get us an empty stack.
Assume the following are pushed with the given order:
3, 1, 5
Then the main stack shall be: (top) 5 1 3 (bottom)
and the min stack shall be: (top) 1 3 (bottom)
At that moment, what happens if I call min()?
1 is popped out of the min stack but what happens to the "1" in the main stack?
The only way to handle this in my opinion is implementing the main stack as a linked list, holding a pointer for each element in the min stack pointing to its location on the main stack and removing that also from the main stack when min() is called.
Any ideas?
Thanks Inverse.Falcon.
For others as slow as I, indeed you only push the mins onto the min stack as they are smaller than the top of the min stack. Say you push (total) 1, 2, 3. 1 is at the bottom of the main, internal stack, then 2, top 3. 1 is the /only/ contents of the min stack. Popping the 1 would require you first to pop 3, then 2, so 1 is throughout, correctly, the min (until you pop it). You don't need to store all numbers on the min stack in min order; the top min on the min stack serves as the min for all numbers above where it (also) is on the main, internal stack.
The idea of using binary representation to keep track of whether the element is included in the main stack or min stack is good. But it will limit this algorithm to 32 items on a 32 bit machine and 64 items on a 64 bit machine. So its better we use the main stack to push and pop all the elements and in addition we will have min stack to update the min element.
one of the possible solution can be-
1.suppose we have stack(can be implemented through class),and top(indicates top position of the stack and min which indicates minimum element in stack
2.pop(),push() can be implemented O(1) as usually(since push and pop takes place on top) and for min
whenever we are inserting an element in to stack we update min as
if(element<min)
min=element
else
min=min
That's not going to work.
You're only thinking about pushing right now, and updating the min that way. Your approach works well here.
But now consider the implications of popping the current min. Since you're not tracking the min values, you would need to search the stack for the new min, and that's not O(1). Simply keeping a single min reference isn't going to work.
Inverse.Falcon, nice approach.
I would like to add one more thing to take care of multiple instance of same value.
As min is popped u will pop it from minStack as well, but if there is one more element down in the stack then min will return wrong value.
So if new element is same as min push min again to both the stacks.
@ramukumar as soon as min is popped out "min" will be out of sync.
@ysjaitawat
actually min indicates min element in stack which is updated accordingly whenever we insert element in to stack whenevr we calll minimun() just return min
1. Create 2 stacks named RegularStack and MinStack.
2. RegularStack: Implement normal push(), pop() and top() functions.
3 MinStack: Maintain the minimum element in RegularStack as its top.
1) Push:
While pushing an element into RegularStack, Compare this element with the top element in MinStack.
If it is smaller, then push that element into MinStack at the same time.
Else do nothing.
2) Pop:
While popping an element out from RegularStack, Compare this element with the top element in MinStack.
If they are equal, we pop out the top element from MinStack at the same time. Otherwise, we do nothing.
3. Get:
Peek element from MinStack and Return.
class StackOperations
{
Stack<int> RegularStack = new Stack<int>();
Stack<int> MinStack = new Stack<int>();
StringBuilder StringBuilderObj = new StringBuilder();
public void PushPopGetMinWithConstantTime()
{
Push(3);
Push(4);
Push(5);
Push(1);
Push(2);
StringBuilderObj.Append("\nElements Pushed into Stack:\n 3, 4, 5, 1, 2");
int minElement = GetMinElement();
StringBuilderObj.Append("\n\nMin Element in Stack:\t" + minElement.ToString());
int poppedElement = Pop();
poppedElement = Pop();
StringBuilderObj.Append("\n\nElements 1, 2 popped out from Stack.\t");
StringBuilderObj.Append("\n\nRemaining Elements in Stack:\n 3, 4, 5");
minElement = GetMinElement();
StringBuilderObj.Append("\n\nMin Element in Stack:\t" + minElement.ToString());
MessageBox.Show(StringBuilderObj.ToString());
}
public void Push(int elementToPush)
{
//Push element to RegularStack
RegularStack.Push(elementToPush);
//If the elementToPush is less than the currentMinElement in MinStack then insert elementToPush to MinStack
//Else do nothing.
int? currentMinElement = null;
if (MinStack.Count > 0)
{
currentMinElement = MinStack.Peek();
}
if (currentMinElement == null || elementToPush < currentMinElement)
{
MinStack.Push(elementToPush);
}
}
public int Pop()
{
if (RegularStack.Count == 0)
{
throw new Exception("No elements in stack to pop");
}
//Pop element from RegularStack.
int elementPopped = RegularStack.Pop();
//Get element from MinStack and check if it is same as elementPopped, then pop out it from the MinStack as well.
int currentMinElement = MinStack.Peek();
if (elementPopped == currentMinElement)
{
MinStack.Pop();
}
return elementPopped;
}
public int GetMinElement()
{
if (MinStack.Count == 0)
{
throw new Exception("No elements in stack to pop");
}
//Get element from MinStack and return.
int currentMinElement = MinStack.Peek();
return currentMinElement;
}
}
<pre lang="java" line="1" title="CodeMonkey634" class="run-this">public class MinStack<T extends Comparable<T>>
- Ryan August 16, 2010{
private Node<T>[] table;
private int size;
public T pop() {
if (this.isEmpty()) {
return null;
}
return table[--size].item;
}
public T min() {
if (this.isEmpty()) {
return null;
}
return table[--size].min;
}
public void push(T item) {
if (size == table.length) {
this.resize();
}
if (this.isEmpty()) {
table[size++] = new Node(item, item);
} else {
Node<T> top = table[size - 1];
T min = top.min.compareTo(item) < 0 ?
top.min : item;
table[size++] = new Node(item, min);
}
}
public boolean isEmpty() {
return this.size == 0;
}
private void resize() {
int newCapacity = 2 * this.table.length;
if (newCapacit < 0)
newCapacity = Integer.MAX_VALUE;
Node<T> newTable = (Node<T>) new Node[newCapacity];
System.arraycopy(table, newTable, size);
this.table = newTable;
}
private static class Node<T>
{
public final T item;
public final T min;
public Node(T item, T min) {
this.item = item;
this.min = min;
}
}
} </pre>