我已经看过两个关于这个问题的堆栈实现,但我真的很困惑,如何才能获得O(1)的操作。
考虑以下例子:
S1[3542761986759]
S2[3332221111111]
这里的想法/算法是:
- 将元素 E 推入 S1
- 检查 S2 的顶部是否 >= E,如果为真,则在 S2 中插入 E
请问有人可以帮我理解这个解决方案吗?
我已经看过两个关于这个问题的堆栈实现,但我真的很困惑,如何才能获得O(1)的操作。
考虑以下例子:
S1[3542761986759]
S2[3332221111111]
3|3 -> 6|3 -> 4|3 -> 2|2 -> 7|2 -> 1|1
这将会在您推入/弹出项目时跟踪分钟数。当然,您需要有一个根节点和一个被指定为“页脚”的节点,以便您可以在O(1)中访问末尾。
或者您也可以反向操作,将项目添加到前面并在每次插入时更改根节点……那样也可以。它会像这样:
1|1 -> 7|2 -> 2|2 -> 4|3 -> 6|3 -> 3|3
如果这样,您将不需要“footer”节点。
这两个都会跟踪当前最小值,以便在推送值时知道第二个最小值是多少。这样,当实际的最小值被推送时,它将以O(1)的时间知道第二个最小值是什么。
/**
* Placing a data item on the top of the stack is called pushing it
* @param element
*
*/
public abstract void push(E element);
/**
* Removing it from the top of the stack is called popping it
* @return the top element
*/
public abstract E pop();
/**
* Get it top element from the stack and it
* but the item is not removed from the stack, which remains unchanged
* @return the top element
*/
public abstract E peek();
/**
* Get the current size of the stack.
* @return
*/
public abstract int size();
/**
* Check whether stack is empty of not.
* @return true if stack is empty, false if stack is not empty
*/
public abstract boolean empty();
}
包 com.java.util.collection.advance.datastructure;
@SuppressWarnings("hiding") public abstract interface MinMaxStack extends Stack {
public abstract int min();
public abstract int max();
}
包 com.java.util.collection.advance.datastructure;
导入 java.util.Arrays;
/** * * @author vsinha * * @param */ public class MyStack implements Stack {
private E[] elements =null;
private int size = 0;
private int top = -1;
private final static int DEFAULT_INTIAL_CAPACITY = 10;
public MyStack(){
// If you don't specify the size of stack. By default, Stack size will be 10
this(DEFAULT_INTIAL_CAPACITY);
}
@SuppressWarnings("unchecked")
public MyStack(int intialCapacity){
if(intialCapacity <=0){
throw new IllegalArgumentException("initial capacity can't be negative or zero");
}
// Can't create generic type array
elements =(E[]) new Object[intialCapacity];
}
@Override
public void push(E element) {
ensureCapacity();
elements[++top] = element;
++size;
}
@Override
public E pop() {
E element = null;
if(!empty()) {
element=elements[top];
// Nullify the reference
elements[top] =null;
--top;
--size;
}
return element;
}
@Override
public E peek() {
E element = null;
if(!empty()) {
element=elements[top];
}
return element;
}
@Override
public int size() {
return size;
}
@Override
public boolean empty() {
return size == 0;
}
/**
* Increases the capacity of this <tt>Stack by double of its current length</tt> instance,
* if stack is full
*/
private void ensureCapacity() {
if(size != elements.length) {
// Don't do anything. Stack has space.
} else{
elements = Arrays.copyOf(elements, size *2);
}
}
@Override
public String toString() {
return "MyStack [elements=" + Arrays.toString(elements) + ", size="
+ size + ", top=" + top + "]";
}
}
包 com.java.util.collection.advance.datastructure;
/** * 时间复杂度为 O(1),用于在给定堆栈中查找最小值和最大值。 * 作者 vsinha * */ public class MinMaxStackFinder extends MyStack implements MinMaxStack {
private MyStack<Integer> minStack;
private MyStack<Integer> maxStack;
public MinMaxStackFinder (int intialCapacity){
super(intialCapacity);
minStack =new MyStack<Integer>();
maxStack =new MyStack<Integer>();
}
public void push(Integer element) {
// Current element is lesser or equal than min() value, Push the current element in min stack also.
if(!minStack.empty()) {
if(min() >= element) {
minStack.push(element);
}
} else{
minStack.push(element);
}
// Current element is greater or equal than max() value, Push the current element in max stack also.
if(!maxStack.empty()) {
if(max() <= element) {
maxStack.push(element);
}
} else{
maxStack.push(element);
}
super.push(element);
}
public Integer pop(){
Integer curr = super.pop();
if(curr !=null) {
if(min() == curr) {
minStack.pop();
}
if(max() == curr){
maxStack.pop();
}
}
return curr;
}
@Override
public int min() {
return minStack.peek();
}
@Override
public int max() {
return maxStack.peek();
}
@Override
public String toString() {
return super.toString()+"\nMinMaxStackFinder [minStack=" + minStack + "\n maxStack="
+ maxStack + "]" ;
}
}
// 测试程序 package com.java.util.collection.advance.datastructure;public static void main(String[] args) {
MinMaxStack<Integer> stack =new MinMaxStackFinder(10);
Random random =new Random();
for(int i =0; i< 10; i++){
stack.push(random.nextInt(100));
}
System.out.println(stack);
System.out.println("MAX :"+stack.max());
System.out.println("MIN :"+stack.min());
stack.pop();
stack.pop();
stack.pop();
stack.pop();
stack.pop();
System.out.println(stack);
System.out.println("MAX :"+stack.max());
System.out.println("MIN :"+stack.min());
}
}
输出:
MyStack [元素=[99, 76, 92, 49, 89, 88, 93, 33, 0, 30], 大小=10, 顶部=9] MinMaxStackFinder [最小栈=MyStack [元素=[99, 76, 49, 33, 0, null, null, null, null, null], 大小=5, 顶部=4] 最大栈=MyStack [元素=[99, null, null, null, null, null, null, null, null, null], 大小=1, 顶部=0]] 最大值:99 最小值:0 MyStack [元素=[99, 76, 92, 49, 89, null, null, null, null, null], 大小=5, 顶部=4] MinMaxStackFinder [最小栈=MyStack [元素=[99, 76, 49, null, null, null, null, null, null, null], 大小=3, 顶部=2] 最大栈=MyStack [元素=[99, null, null, null, null, null, null, null, null, null], 大小=1, 顶部=0]] 最大值:99 最小值:49
如果您有任何问题,请告诉我。
谢谢, VIKASH SINHA
这是不可能的。否则,您将能够在线性时间内实现比较排序:首先每个元素都以O(1)的时间推入,总共O(n)的时间,然后n次在O(n)的总时间内获取最小值。
由于已知O(n log n)是比较排序的下限,因此不存在具有O(1)推送和查找最小值的解决方案。
编辑:如Gabe所指出的那样,将“排序”替换为“比较排序”。
S2 [321]
- Bitterblue