我有一个
list<int> input = //from db of one million records
<100> 记录。
虽然我知道使用input.OrderByDescending().Skip(1).Take(1)
可以解决问题,但如果我有100万条记录,那么使用OrderBY
不是最佳做法。
在这种情况下,当我们有更多记录时,哪种解决方案最好?
答案 0 :(得分:4)
在跟踪max
以及max2
时扫描列表,您将获得O(N)
与O(N * log(N))
时间复杂度:
// Maximum value
int max = Math.Max(input[input.Count - 1], input[input.Count - 2]);
// Second greatest
int max2 = Math.Min(input[input.Count - 1], input[input.Count - 2]);
// i >= 0: Comparing with 0 is slightly faster then with Count
for (int i = input.Count - 3; i >= 0; --i) {
int v = input[i];
if (v >= max) {
max2 = max;
max = v;
}
else if (v > max2)
max2 = v;
}
修改:如果重复应忽略(请参阅下面的评论),因此[1, 2, 3, 4, 4, 4, 4]
的答案应为{ {1}},而不是3
:
4
答案 1 :(得分:2)
你可以通过跟踪下一个最大值并在列表中迭代一次来完成。
DROP LOGIN [XXXXXX\user10]
答案 2 :(得分:2)
如果您的列表仅包含不同的值,您还可以执行以下操作:
var max = input.Max();
input.Remove(max);
var result = input.Max();
答案 3 :(得分:0)
这是一个只使用LINQ和C#7元组迭代一次的解决方案:
var input = Enumerable.Range(0, 101);
var topTwo = input.Aggregate((Biggest: Int32.MinValue, SecondBiggest: Int32.MinValue),
(acc, next) =>
{
if (next > acc.Biggest)
{
acc.SecondBiggest = acc.Biggest;
acc.Biggest = next;
}
if (next < acc.Biggest && next > acc.SecondBiggest)
acc.SecondBiggest = next;
return acc;
});
WriteLine(topTwo.SecondBiggest); // 99