【问题标题】:optimised algorithm to find maximum value in stack优化算法以在堆栈中找到最大值
【发布时间】:2016-05-17 23:37:20
【问题描述】:
  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);

此代码在堆栈中找到最大值,运行良好,但我希望优化其性能,以便它可以处理非常大的堆栈。有人可以提出更好的算法吗?

【问题讨论】:

  • 为什么是Stack?或任何Collection
  • 不可能。您访问的最后一个值始终可以具有最大值。
  • 如果你不能用一个可以在O(log(n))(如二叉搜索树)或O(1)(如哈希表)中实现搜索的数据结构更改Stack,那么我不要认为你能获得比线性更好的性能。
  • 如果可以更改数据结构,最好将Max-Heap 添加到建议中
  • 您提到要针对大量输入进行优化。如果您谈论可伸缩性,则无法优化您的代码。我相信您可以使用某些方法而不是其他方法,尽管它不会特别提到更大输入的运行时间。

标签: java algorithm data-structures


【解决方案1】:

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

唯一的一种选择是拥有Sorted 数据结构,其中元素是有序的。这使您可以在O(1) 复杂性下获得最大的收益,但排序本身需要O(n*log(n)),如果您只需要获取最大元素,这是没有意义的。

【讨论】:

    【解决方案2】:

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

    您可以滚动您自己的实现,该实现适用于Comparable&lt;T&gt; 或仅用于维护两个堆栈的整数,一个用于元素,另一个用于最大元素,最大堆栈将保持当前最大值,当您弹出时,您弹出来自两个堆栈。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        根据您的实际需求,您可以进行其他权衡。

        以 1 个 Integer 对象的存储成本,您可以在不排序的情况下以 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();
            }
        }
        

        另请注意,这不是线程安全的。

        【讨论】:

          【解决方案5】:

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

          Refer this for more implementation details

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-12-24
            • 2021-08-05
            • 1970-01-01
            • 2011-11-24
            • 1970-01-01
            • 2012-11-04
            • 2018-03-29
            相关资源
            最近更新 更多