Подтвердить что ты не робот

Вставить, удалить, max в O (1)

Может ли кто-нибудь сказать мне, какая структура данных поддерживает операцию insert/delete/maximum в O (1)?

4b9b3361

Ответ 1

Это классический вопрос интервью и обычно представлен следующим образом:

Создайте структуру данных, подобную стеку, которая выполняет операции push, pop и min (или max) в O (1) раз. Нет ограничений по пространству.

Ответ: вы используете два стека: основной стек и минимальный (или максимальный) стек.

Итак, например, после нажатия 1,2,3,4,5 на стек ваши стеки будут выглядеть так:

MAIN   MIN
+---+  +---+
| 5 |  | 1 |
| 4 |  | 1 |
| 3 |  | 1 |
| 2 |  | 1 |
| 1 |  | 1 |
+---+  +---+

Однако, если вы должны были нажать 5,4,3,2,1, стеки выглядели бы так:

MAIN   MIN
+---+  +---+
| 1 |  | 1 |
| 2 |  | 2 |
| 3 |  | 3 |
| 4 |  | 4 |
| 5 |  | 5 |
+---+  +---+

Для 5,2,4,3,1 у вас будет:

MAIN   MIN
+---+  +---+
| 1 |  | 1 |
| 3 |  | 2 |
| 4 |  | 2 |
| 2 |  | 2 |
| 5 |  | 5 |
+---+  +---+

и т.д.

Вы также можете сэкономить некоторое пространство, нажав на минимальный стек только при изменении минимального элемента, если элементы, как известно, отличаются друг от друга.

Ответ 2

Комментарий @KennyTM указывает важную недостающую деталь - вставьте туда и удалите откуда. Поэтому я собираюсь предположить, что вы всегда хотите вставлять и удалять только с одного конца, как стек.

Вставка (push) и Delete (pop) - O (1).

Чтобы получить Max в O (1), используйте дополнительный стек для записи текущего max, который соответствует основному стеку.

Ответ 3

В следующем решении используется O (1) дополнительная память и O (1) время для операций max, push и pop. Сохраняйте переменную max, которая будет отслеживать текущий максимальный элемент в любое конкретное время. Давайте используем тот факт, что при обновлении max все элементы в стеке должны быть меньше, чем новый max-элемент. Когда происходит операция push и новый элемент (newElement) больше текущего max, мы нажимаем max + newElement в стеке и обновляем max = newElement.

Когда мы делаем операцию pop, и мы обнаруживаем, что текущий popped элемент больше текущего max, тогда мы знаем, что это место, где мы обновили наш стек, чтобы удерживать max + elem. Таким образом, фактический элемент, который нужно вернуть, - max и max = poppedElem - max.

Например, если мы нажимаем 1, 2, 3, 4, 5, то стек и максимальная переменная будут выглядеть следующим образом:

MAIN       Value of MAX
+---+      +---+
| 9 |      max = | 5 |
| 7 |      max = | 4 |
| 5 |      max = | 3 |
| 3 |      max = | 2 |
| 1 |      max = | 1 |
+---+      +---+

Теперь давайте скажем, что мы выталкиваем элемент, мы будем в основном pop, max element (начиная с top > max) и обновляем максимальный элемент до (top-max)

MAIN       Value of MAX
+---+      +---+
| 7 |      max = | 4 | = (9-5)
| 5 |      max = | 3 |
| 3 |      max = | 2 |
| 1 |      max = | 1 |
+---+      +---+

Теперь скажем, что мы нажимаем числа 5, 4, 3, 2, 1, стек будет выглядеть так:

MAIN       Value of MAX
+---+      +---+
| 1 |      max = | 5 |
| 2 |      max = | 5 |
| 3 |      max = | 5 |
| 4 |      max = | 5 |
| 5 |      max = | 5 |
+---+      +---+

Когда мы выходим, верхняя часть стека складывается, так как top < max и max остается неизменным.

Ниже приведен псевдокод для каждой операции для лучшего понимания.

Elem max;
void Push(Elem x){
    if x < max :
        push(x);
    else{
        push(x+max);
        max = x;
    }
}
Elem Pop(){
    Elem p = pop();
    if |p| < |max|:
        return p;
    else{
        max = p - max;
        return max;
    }
}
Elem Max(){
    return max;
}

push и pop - обычные операции стека. Надеюсь, это поможет.

Ответ 4

Если вы используете только сравнения, вам будет трудно найти такую ​​структуру данных.

Например, вы могли бы вставить n элементов, get max, delete max и т.д. и могли сортировать числа в O (n) времени, тогда как теоретическая нижняя граница - Omega (nlogn).

Ответ 5

Хотя @Can Berk Güder answer прав. Но если у нас есть пространственное ограничение, мы можем сделать намного лучше, даже если элементы не различны. Для получения дополнительной информации см. Мой ответ здесь с реализацией в Java.

Ответ 6

Ниже программа отслеживает максимальные элементы в стеке таким образом, что в любой момент времени верхний указатель дает нам максимум в стеке: Таким образом, max будет O (1), и мы можем найти max max [N]

ITEM   MAX

+---+  +---+
| 1 |  | 1 |
| 10|  | 10|
| 9 |  | 10|
| 19|  | 19| <--top
+---+  +---+

Программа Java:

public class StackWithMax {

private int[] item;
private int N = 0;
private int[] max;

public StackWithMax(int capacity){
    item = new int[capacity];//generic array creation not allowed
    max = new int[capacity];
}

public void push(int item){
    this.item[N++] = item;
    if(max[N-1] > item) {
        max[N] = max[N-1];
    } else {
        max[N] = item;
    }
}

public void pop() {
    this.item[N] = 0;
    this.max[N] = 0;
    N--;
}

public int findMax(){
    return this.max[N];
}
public static void main(String[] args) {
    StackWithMax max = new StackWithMax(10);
    max.push(1);
    max.push(10);
    max.push(9);
    max.push(19);
    System.out.println(max.findMax());
    max.pop();
    System.out.println(max.findMax());


}

}

Ответ 7

Как уже отмечалось, в вопросе отсутствует какая-то информация. Вы не указываете, нужно ли вставлять/удалять, а также характер данных, с которыми мы имеем дело.

Некоторые идеи, которые могут быть полезны: вы говорите,

Вставить/удалить/максимальную операцию в O (1)

заметим, что если мы можем вставить, удалить и найти maximun в O (1), то мы можем использовать эту хипотехническую технику для сортировки в O (n), потому что мы можем вставить n элементов, а затем взять max/delete и мы все сортируем. Было доказано, что ни один алгоритм сортировки, основанный на сравнениях, не может сортировать меньше, чем O (nlogn), поэтому мы знаем, что никакой подход, основанный на сравнении, не будет работать. На самом деле одним из самых быстрых способов сделать это является очередь Brodal, но время ее удаления превышает O (1).

Возможно, решение похоже на дерево radix, сложность всех этих операций связана с длиной ключа, как и количество ключей. Это справедливо только в том случае, если они позволяют связать длину ключа с каким-либо другим числом, поэтому вы можете считать его постоянным.

Но, возможно, это было не что-то общее. Другая интерпретация заключается в том, что вставка/удаление - это классический стек. В этом ограниченном случае вы можете использовать двойной стек, который Can Berk Güder дал вам.

Ответ 8

Хэш-таблица может поддерживать вставку/удаление в O (1), но не знает о максимуме. Вам, вероятно, придется как-то следить за этим.