I have already seen two stack implementation of this question but I am really confused as how one could get O(1) operation. consider following example:
S1[3542761986759]
S2[3332221111111]
The idea/algorithm here is
- Push element E on S1
- Check to see if top of S2 >= E and if true, insert E on S2
But when getMin is called, we return top of S2 but that leaves S2 in weird state as S2 contains repeated current min elements, so the solution is to search next minimum element in S2 and return it. This is O(n).
Can anyone please help me to understand the solution?
I am posting the complete code here to find min and mx in a stack. Time complexity will be O(1)
package com.java.util.collection.advance.datastructure;
/** * * @author vsinha * */ public abstract interface Stack {
}
package com.java.util.collection.advance.datastructure;
@SuppressWarnings("hiding") public abstract interface MinMaxStack extends Stack {
}
package com.java.util.collection.advance.datastructure;
import java.util.Arrays;
/** * * @author vsinha * * @param */ public class MyStack implements Stack {
}
package com.java.util.collection.advance.datastructure;
/** * Time complexity will be O(1) to find min and max in a given stack. * @author vsinha * */ public class MinMaxStackFinder extends MyStack implements MinMaxStack {
}
// Test program
package com.java.util.collection.advance.datastructure;
import java.util.Random;
public class MinMaxStackFinderApp {
}
Output:
MyStack [elements=[99, 76, 92, 49, 89, 88, 93, 33, 0, 30], size=10, top=9] MinMaxStackFinder [minStack=MyStack [elements=[99, 76, 49, 33, 0, null, null, null, null, null], size=5, top=4] maxStack=MyStack [elements=[99, null, null, null, null, null, null, null, null, null], size=1, top=0]] MAX :99 MIN :0 MyStack [elements=[99, 76, 92, 49, 89, null, null, null, null, null], size=5, top=4] MinMaxStackFinder [minStack=MyStack [elements=[99, 76, 49, null, null, null, null, null, null, null], size=3, top=2] maxStack=MyStack [elements=[99, null, null, null, null, null, null, null, null, null], size=1, top=0]] MAX :99 MIN :49
Let me know if you have any issues.
Thanks, VIKASH SINHA
Using a linked list store the current minimum value. When you add a new number it looks at the previous min and changes the current min to the current value if the current value is lower.
E.g... Assume you have the data: 3, 6, 4, 2, 7, 1. Then this is what the list would look like
value|min
That'll keep track of the mins as you push/pop items. Granted you'll need to have a root node and a node designated as a "footer" so you can access the end in O(1).
Or you could go backwards with it and add things to the front and change the root node every insert... that would work too. It would be something like this:
Then you wouldn't need the "footer" node.
Both of these will keep track of the current min value for when the value was pushed. That way when the actual min value is pushed, it will know what the second min value was in O(1).
This is not possible. Otherwise you'd be able to implement comparison sorting in linear time: First push all elements in O(1) each, O(n) total time, and then n times get the minimum in O(n) total time.
As it is known that O(n log n) is a lower bound for comparison sorting, a solution with O(1) push and findmin can't exist.
Edit: Replaced "sorting" by "comparison sorting" as noted by Gabe.