假设我们有一个包含整数的列表,我们需要找到min&最大。最好的方法是什么?我可以想到以下几点:
如果读取次数远高于写入次数;以排序的方式保持列表。每当添加一个数字时;以排序的方式添加它。 现在要获得最小值和最大值,我们可以得到它的第一个和最后一个元素 列表
- 醇>
如果写入次数高于读取次数;迭代列表并返回结果。但这是O(n)看起来很昂贵。
还有其他更好的方法吗?
答案 0 :(得分:4)
假设您可以观察到列表中的任何突变,您可以存储(缓存)最小值和最大值,并可能在添加/删除数字时更新缓存值。此时,列表的顺序无关紧要。
答案 1 :(得分:2)
您可以使用Collection.max()和Collection.min()静态方法...
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Collections.html
使用SortedSet让集合自动排序。
答案 2 :(得分:2)
我会提出一个有趣的想法:
假设您确实经常删除,但读取次数多于写入次数,您可以保留一个项目数组(对象表示整数,其中两个引用已添加项目的最小值和最大值),缓存引用上一个最小值和最大值(与@akaIDIOT解决方案的区别在于这只是引用)。
堆栈中的每个值都指向前一个最大值和前一个最小值。
添加项目也将采用O(1),找出最小值和最大值也需要O(1)。
更新中描述了删除项目:
缺点是内存消耗更多。
如果此解决方案有误,我会将其删除,如果您发现任何问题请发表评论,无需进行投票!
<强>更新强>
@akaIDIOT在他的评论中提到了一个我错过的案例。如果您有多个最大值或最小值,该怎么办?
在这种情况下以及其他情况下,删除最大值将要求更新指向它的所有对象,这将是max O(n),但我认为平均而言它仍将保持O(1)。 如果所有值都不同,则始终为O(1)
答案 3 :(得分:1)
您还可以使用min/max heap
类似的数据结构(红黑树)来保持整数。获取最小值/最大值将花费O(1)
时间并插入新元素将花费O(log n)
时间。
答案 4 :(得分:0)
假设您支持从列表中删除整数,无论哪个更高(读取或写入),使用排序列表可以使事情更容易并提供更好的性能。
答案 5 :(得分:0)
您可以拥有一个维护最小值和最大值的自定义列表。这将为您提供O(1)插入,O(1)读取Min和Max以及O(N)删除,但仅限于您删除min或max。
的伪代码:
public MinMaxList
{
property Min;
property Max;
method Add (int newValue)
{
if (Min is null OR newValue < Min)
Min = newValue;
if (Max is null OR newValue > Max)
Max = newValue;
}
method Delete (int value)
{
if (value = Min or value = Max)
//Rescan list to determine new Min and Max values. This is O(N).
}
}