问题:从整数集合中获取最高数字的最有效方法
我最近在讨论这个问题,我有两个解决方案。 1)迭代集合并找到最高编号(下面的代码) 2)使用排序算法。
第一种方法将具有O(n)效率
int getHighestNumber(ArrayList<Integer> list)
{
if(list != null && list.size() > 0)
{
if(list.size() == 1)
return list.get(0);
int maxNum = list.get(0);
for(int item:list)
{
if(item > maxNum)
maxNum = item;
}
return maxNum;
}
return null;
}
我的问题是“任何排序算法都可以在任何给定的输入上击败它(例如,如果集合已经排序了吗?”) 还有其他比这更好的方法吗?
答案 0 :(得分:4)
如果Collection已经排序,您可以找到O(1)
中最大的元素(假设Collection
支持随机访问或O(1)
访问Collection
的结尾持有最大元素 - 如果最大元素是第一个,任何集合都会通过其O(1)
为您提供Iterator
访问权限。在这种情况下,你不必对它进行排序。
当输入被排序时,任何排序都至少需要O(n)
(当它不是时,至少O(nlog(n))
),因为您无法验证输入是否已排序没有超过所有元素。因此,排序算法无法超越您的O(n)
解决方案。
答案 1 :(得分:1)
你的问题暗示了它自己的答案。这取决于集合本身的来源。也就是说,您对数据集的了解越多,您就可以更快地设计启发式算法来获得所需的答案。
所以,如果您的列表已经排序,那么列表[0]或列表[len-1]将是最高的......
次要答案还取决于&#39;搜索列表的频率是多少?&#39;。如果这是一次性搜索,那么只需迭代最高的列表将是最快的。 如果您将重复执行此操作(例如,收集各种指标),那么首先使用“快速排序”对其进行排序可能是您最好的。
答案 2 :(得分:0)
您的问题是,有两个选项可以找到未排序列表的最大值。
选项1:
使用问题getHighestNumber
选项2: 使用世界上最有效的排序算法对列表进行排序,然后获取列表的最后一个值。
那么在效率方面什么是最佳选择。
我的回答:选项1,如果数组未排序,则排序算法不能超过选项1。
答案 3 :(得分:0)
使用Java 8,您可以使用max
API找到Stream
,但这并不能解决O(n)问题。但是,元素访问的计算成本低于普通迭代器;
list.stream().mapToInt(i -> i).max().getAsInt();
答案 4 :(得分:0)
这是我最喜欢的论点,我总是用它来快速判断这样的问题:
你必须至少使用
O(N)
查看所有元素,即 I / O时间。
在不考虑太多的情况下,它可以说服自己,在复杂性方面,任何算法都无法击败任何O(N)
算法。希望它有意义。