优化算法以在堆栈中找到最大值

时间:2016-02-08 10:30:39

标签: java algorithm data-structures

  Stack<Integer> st= new Stack<Integer>();
  int max=(int) st.peek();
  int top=0;
  for(Integer loopVal:st)
  {
     if(max<loopVal)
         max=loopVal;
  }
  System.out.println(max);

这个代码在堆栈中找到最大值,但是工作得非常好,但我希望优化它的性能,以便它可以处理非常大的堆栈。有人可以提出更好的算法吗?

5 个答案:

答案 0 :(得分:2)

算法的复杂性O(n) - 线性。在找到最大值之前,您需要处理所有元素。使用给定的数据结构,您将无法获得更好的复杂性。

唯一的选择是拥有Sorted数据结构,其中元素是有序的。这允许您以O(1)复杂度获得最大值,但排序本身需要O(n*log(n)),如果您只需要获取max元素,则没有任何意义。

答案 1 :(得分:1)

无法在非线性时间内从堆栈中获取最大值。实际上,堆栈中的元素不必具有可比性,因此对于T中可以放入的Stack,每个Comparable<T>都不存在max的概念。

你可以自己实现适用于@的实现,或只是你维护两个堆栈的整数,一个用于元素,另一个用于max元素,最大堆栈将保持当前最大值,当你弹出时,你从两个堆栈弹出。

答案 2 :(得分:0)

O(n)是在搜索堆栈中的max元素时可以获得的最佳时间复杂度,因为最大元素可以在堆栈中的任何位置。您可以做的一件事是在进行堆栈时,即将元素插入堆栈时将值与max变量进行比较,如果插入的值大于max变量值,则更新max变量。插入也将采用线性时间,但仍然比在制作堆栈后单独找到最大元素更好。这种方法的问题是如果你从堆栈中弹出元素,你可能会在某个时候弹出max元素,并且知道如何在不扫描堆栈的情况下找到新的最大值。

答案 3 :(得分:0)

根据您的实际要求,您可以进行另一次折扣。

在1个整数对象的存储成本下,您可以获得复杂度 O(1)的最大值,而不进行排序,PUSH的成本为 O(1)从堆栈弹出元素时, O(n)成本。

public class IntStackWithMax {

    private Integer maxVal = Integer.MIN_VALUE;
    private Vector<Integer> values = new Vector<Integer>();

    // cost O(1)
    public Integer getMaxVal() {
        return maxVal;
    }

    //cost O(1)
    public boolean push(Integer item) {
        maxVal = Math.max(maxVal, item);
        return values.add(item);
    }

    //cost O(n) (!!!)
    public Integer pop() {
        Integer result = values.remove(values.size() - 1);
        maxVal = Collections.max(values);
        return  result;
    }

    //cost O(1)
    public Integer peek() {
        return values.lastElement();
    }
}

请注意,这是 NOT 线程安全。

答案 4 :(得分:0)

如果空间复杂性可能受到影响,您可以创建另一个堆栈,并在将新的最小值推入原始堆栈时继续推送最小值...

Refer this for more implementation details