У меня проблема, в которой я должен искать максимальный элемент в стеке. Я создал свой собственный класс стека и использовал следующий подход:

   Node node = top; //created a new node which points to the top of stack

   int max = node.data;  //max contains the value of the top node

   while(node != null) {
           if(node.data > max) {
              max = node.data;
           }
           node = node.next;
    }

   //Print the value of max.

Может ли кто-нибудь предложить более эффективный способ сделать это?

0
artenson.art98 13 Июл 2017 в 09:09
2
Если ваш стек как-то не отсортирован, нет более быстрого способа, чем O (n) !? Вы можете использовать многопоточное решение, но это может быть все.
 – 
xander
13 Июл 2017 в 09:10

2 ответа

Поддержите два стека:

  1. состоят из всех узлов.
  2. всегда держите узел Max наверху, что упрощает получение максимального элемента каждый раз.

Код выглядит так:

import java.util.Stack;

public class StackWithMax extends Stack<Integer> {

Stack<Integer> s2;

public StackWithMax() {
    s2 = new Stack<Integer>();      
}

public void push(int value){
    if (value >= max()) {
        s2.push(value);
    }
    super.push(value);
}

public Integer pop() {
    int value = super.pop();
    if (value == max()) {
        s2.pop();           
    }
    return value;
}

public int max() {
    if (s2.isEmpty()) {
        return Integer.MIN_VALUE;
    } else {
        return s2.peek();
    }
  }
} 
3
amrender singh 13 Июл 2017 в 09:15
Если вы делаете это так, почему бы просто не сохранить int max в классе стека вместо другого стека !?
 – 
xander
13 Июл 2017 в 09:24
1
Если вы просто сохраните один max, тогда, когда вы вытащите элемент, вам придется пройти через весь стек, чтобы снова вычислить max.
 – 
ajb
13 Июл 2017 в 09:26
Чем нам нужно пройти через весь стек, чтобы снова найти макс.
 – 
amrender singh
13 Июл 2017 в 09:27
Когда элемент удаляется из стека, и если это максимум, вам нужно будет перебрать весь стек, чтобы найти предыдущее второе по величине значение, которое является новым максимумом ...
 – 
assylias
13 Июл 2017 в 09:28
1
Тот факт, что вы не переопределяете должным образом метод push, делает эту ошибку весьма подверженной.
 – 
Evan Darke
13 Июл 2017 в 09:32

Если вас устраивает использование дополнительного места, мы можем выполнить getMax () за O (1) раз. Идея состоит в том, чтобы использовать PriorityQueue на основе компаратора, который возвращает максимум два элемента. Ваш PriorityQueue будет состоять из элементов, упорядоченных в соответствии с вашим компаратором. Каждый раз, когда вы помещаете элемент в свой стек, вы также нажимаете максимальный элемент, соответствующий этому элементу, в PriorityQueue. Возьмем пример:

Предположим, в вашем стеке вы нажимаете элемент 3. Затем в вашем priorityQueue pQ вы должны предложить 3. В этот раз 3 будет максимальным элементом, соответствующим 3 в стеке.

Давайте вставим 5 в стопку S. Предложите 5 в pQ. Так как 5> 3, порядок элементов в pQ будет равен 5 3. Давайте вставим 4 в S. Предложим также 4 в pQ. pQ теперь будет содержать элементы: 5 4 3. Если вы выполните getMax (), вы получите заголовок pQ, который занимает время O (1), поскольку максимальный элемент всегда находится на вершине pQ.

В случае S.pop () вы можете удалить соответствующий всплывающий элемент из pQ, а также за время O (1), если вы сохраняете pQ в форме LinkedList. Следовательно, все эти операции действительно займут время O (1).

Следуя той же логике, вы также можете выполнить popMax () за O (1) раз. Просто верните заголовок pQ и удалите соответствующий узел из стека, что снова можно сделать за O (1) времени.

Вот как может быть структура обоих:

public class Node{
    int data;
    Node next;
    Node(int data){
        this.data = data;
        next = null;
    }
}

PriorityQueue<Node> pQ = new PriorityQueue<Node>();
Stack<Node> S = new Stack<Node>();
0
CodeHunter 13 Июл 2017 в 11:32