是否有可能在数组中找到2个最大的数字,并且只能遍历集合一次?
我把这作为面试问题并没有及时得到它。
答案 0 :(得分:29)
看起来很简单..
int[] nums = { 3, 1, 4, 1, 5, 9, 2, 6 };
int max1 = -1;
int max2 = -1;
foreach (int num in nums)
{
if (num > max1) { max2 = max1; max1 = num; }
else if (num > max2) { max2 = num; }
}
例如:
// 3: max2 = -1; max1 = 3;
// 1: max2 = 1;
// 4: max2 = 3; max1 = 4;
快速解释:
答案 1 :(得分:1)
通常,对于任何K,您可以使用单次传递找到数组中的K个最大(或最小)数字。总时间复杂度将为O(NK),其中N是数组的大小:
保留一个最多包含K个元素的数字排序列表。遍历数组和每个项目:
最后,列表将包含K个最大的项目,这就是我们想要的。
但这个解决方案很慢。使用自平衡二叉搜索树或跳过列表,您可以达到O(N log K)。 (因为在一般情况下不可能比O(N log N)更快地排序,并且如果我们设置K = N,这个方法可以用于对整个数组进行排序,这看起来是我们能得到的最好的。)
在K = 2的情况下,您不需要所有这些重型机械。表示列表中两个位置的两个变量就足够了。
答案 2 :(得分:0)
是的,确实如此。在遍历列表时,记录找到的最大数字,每当找到更大的数字时,在找到最大的数字之前,将找到的最大数字保存到第二大。如果该值大于第二大值,则更新第二大值。