在O(1)中实现堆栈(push,pop和findmin)

时间:2010-11-03 23:46:07

标签: stack implementation

我已经看过这个问题的两个堆栈实现,但我真的很困惑,因为如何获得O(1)操作。 请考虑以下示例:

S1[3542761986759]
S2[3332221111111]

这里的想法/算法是

  1. 在S1上推送元素E
  2. 检查S2的顶部是否> = E,如果为真,则在S2上插入E
  3. 但是当调用getMin时,我们返回S2的顶部,但是由于S2包含重复的当前最小元素,因此S2处于奇怪状态,因此解决方案是搜索S2中的下一个最小元素并返回它。这是O(n)。

    有谁可以帮我理解解决方案?

3 个答案:

答案 0 :(得分:2)

使用链接列表存储当前最小值。当您添加新数字时,它会查看前一个最小值,并在当前值较低时将当前最小值更改为当前值。

E.g ...假设您有数据:3,6,4,2,7,1。这就是列表的样子

值|分钟

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

然后你不需要“页脚”节点。

这两个都将跟踪推送值时的当前最小值。这样,当推动实际最小值时,它将知道O(1)中的第二个最小值是什么。

答案 1 :(得分:0)

这是不可能的。否则,您将能够在线性时间内实现比较排序:首先按O(1)中的所有元素,O(n)总时间,然后n次在O(n)总时间内得到最小值。

众所周知,O(n log n)是比较排序的下限,不能存在O(1)push和findmin的解决方案。

修改:按照Gabe的说法,通过“比较排序”替换“排序”。

答案 2 :(得分:0)

我在这里发布完整代码,以便在堆栈中找到min和mx。  时间复杂度将为O(1)

package com.java.util.collection.advance.datastructure;

/ **  *  * @author vsinha  *  * / 公共抽象接口Stack {

/**
 * 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();

}

package com.java.util.collection.advance.datastructure;

@SuppressWarnings( “隐藏”) 公共抽象接口MinMaxStack扩展了Stack {

public abstract int min();

public abstract int max();

}

package com.java.util.collection.advance.datastructure;

import java.util.Arrays;

/ **  *  * @author vsinha  *  * @param  * / 公共类MyStack实现了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 + "]";
}

}

package com.java.util.collection.advance.datastructure;

/ **  *时间复杂度将为O(1)以在给定堆栈中找到最小值和最大值。  * @author vsinha  *  * / 公共类MinMaxStackFinder扩展MyStack实现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;

import java.util.Random;

公共类MinMaxStackFinderApp {

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 [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]] 最高: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]] 最高:99 MIN:49

如果您有任何问题,请告诉我。

谢谢, VIKASH SINHA