Реализация стека (push, pop и findmin) в O (1) - PullRequest
3 голосов
/ 04 ноября 2010

Я уже видел реализацию этого вопроса с двумя стеками, но я действительно запутался, как можно получить операцию O (1).рассмотрим следующий пример:

S1[3542761986759]
S2[3332221111111]

Идея / алгоритм здесь такой:

  1. Нажмите элемент E на S1
  2. Проверьте, нет ли вершины S2> = E иесли true, вставьте E в S2

Но когда вызывается getMin, мы возвращаем начало S2, но это оставляет S2 в странном состоянии, так как S2 содержит повторяющиеся текущие минимальные элементы, поэтому решение состоит в том, чтобы искать следующий минимумэлемент в S2 и вернуть его.Это O (n).

Может кто-нибудь помочь мне разобраться в решении?

Ответы [ 3 ]

2 голосов
/ 24 мая 2011

Используя связанный список, сохраните текущее минимальное значение. Когда вы добавляете новый номер, он просматривает предыдущий мин и меняет текущий мин на текущее значение, если текущее значение ниже.

Например ... Предположим, у вас есть данные: 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).

0 голосов
/ 11 сентября 2014

Я выкладываю полный код здесь, чтобы найти min и mx в стеке. Временная сложность составит O (1)

пакет 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();

}

пакет com.java.util.collection.advance.datastructure;

@ SuppressWarnings ( "прятались") открытый абстрактный интерфейс MinMaxStack расширяет стек {

public abstract int min();

public abstract int max();

}

пакет com.java.util.collection.advance.datastructure;

import java.util.Arrays;

/ ** * * @author vsinha * * @param * / открытый класс MyStack реализует стек {

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), чтобы найти минимальное и максимальное значения в данном стеке. * @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 + "]" ;
}

}

// Тестовая программа

пакет 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], размер = 10, top = 9] MinMaxStackFinder [minStack = MyStack [elements = [99, 76, 49, 33, 0, ноль, ноль, ноль, ноль, ноль], размер = 5, топ = 4] maxStack = MyStack [elements = [99, ноль, ноль, ноль, ноль, ноль, ноль, ноль, ноль, ноль, ноль], размер = 1, верх = 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, ноль, ноль, ноль, ноль, ноль, ноль, ноль], размер = 3, верх = 2] maxStack = MyStack [elements = [99, ноль, ноль, ноль, ноль, ноль, ноль, ноль, ноль, ноль, ноль], размер = 1, верх = 0]] МАКС: 99 MIN: 49

Дайте мне знать, если у вас возникнут проблемы.

Спасибо, ВИКАШ СИНХА

0 голосов
/ 04 ноября 2010

Это невозможно.В противном случае вы могли бы реализовать сортировку сравнения по линейному времени: сначала вставьте все элементы в O (1) каждый, общее время O (n), а затем n раз получите минимальное общее время O (n).

Поскольку известно, что O (n log n) является нижней границей для сортировки сравнения, решение с O (1) push и findmin не может существовать.

Редактировать: Заменил "сортировку" на "сортировку сравнения", как отметил Гейб.

...