我最近接受了Codility测试,问题是在数字序列中找到第一个唯一的数字。虽然我使用LINQ得到了正确的结果,但它在计算上显然太昂贵而且不够可扩展。
我如何改进我的解决方案?
var a = new int[] {1, 2, -3, 4, 5, -6, 0, 8, 9, 1, 2};
const int expected = -3;
var retVal = -1;
var y = a.GroupBy(z => z).Where(z => z.Count() == 1).Select(z => z.Key).ToList();
if (y.Count > 0) retVal = y[0];
Console.Write(retVal==expected);
答案 0 :(得分:0)
这个怎么样:
var result = a.ToLookup(i => i).First(i => i.Count() == 1).Key;
这应该给-3。
它使用列表中的每个数字创建一个Lookup
对象,并使用相同数字的值。
如果是重复项,则在每个键下创建多个条目。第一个唯一值将是Lookup
中第一个具有一个条目的组。
(您可以轻松使用GroupBy
,而不是ToLookup
。最终结果将是相同的。)
答案 1 :(得分:0)
试试这个
var result = a.GroupBy(g => g).Where(w => w.Count() == 1).Select(s => s.Key).FirstOrDefault();
答案 2 :(得分:0)
我决定测试上面发布的各种答案,并使用StopWatch类计算滴答数。
更改y.Count> 0到y.Any()导致第二个最低滴答数,但最大的减少属于该组,来自Baldrick的评论
为了获得平均值,每次测试运行50次。
Ticks
Min Max Avg Actual
2 14502 584 -3 Original
2 919 40 -3 if (y.Any()) actual = y[0];
2 1423 60 -3 a.GroupBy(g => g).Where(w => w.Count() == 1)
.Select(s => s.Key)
.FirstOrDefault();
2 1553 65 -3 a.ToLookup(i => i).First(i => i.Count() == 1).Key;
2 317 15 -3 a.GroupBy(i => i).First(i => i.Count() == 1).Key;