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);
这个代码在堆栈中找到最大值,但是工作得非常好,但我希望优化它的性能,以便它可以处理非常大的堆栈。有人可以提出更好的算法吗?
答案 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)
如果空间复杂性可能受到影响,您可以创建另一个堆栈,并在将新的最小值推入原始堆栈时继续推送最小值...