在List中查找第一个可用的long

本文关键字:long 第一个 查找 List | 更新日期: 2023-09-27 18:12:23

好的,这应该很有趣。

假设我有以下代码:

在这个例子中,第一个可用的号码是2

List<long> myList = new List<long>(){0,1,10,3};

在这个例子中,第一个可用的数字是'4'。

List<long> myList = new List<long>(){0,1,2,3};

任何想法?

在List<long>中查找第一个可用的long

所以你说的"可用"是指"列表中不存在的最小非负数"?

我很想这样写:

HashSet<long> existing = new HashSet<long>(list);
for (long x = 0; x < long.MaxValue; x++)
{
    if (!existing.Contains(x))
    {
        return x;
    }
}
throw new InvalidOperationException("Somehow the list is enormous...");

编辑:或者,您可以对列表进行排序,然后找到索引与值不相同的第一个值…

var ordered = list.OrderBy(x => x);
var differences = ordered.Select((value, index) => new { value, index })
                         .Where(pair => pair.value != pair.index)
                         .Select(pair => (int?) pair.index);
var firstDifference = differences.FirstOrDefault();
long nextAvailable = firstDifference ?? list.Count;

最后一行处理的是列表从0开始连续的情况。另一个选项是:

var nextAvailable = list.Concat(new[] { long.MaxValue })
                        .OrderBy(x => x)
                        .Select((value, index) => new { value, index })
                        .Where(pair => pair.value != pair.index)
                        .Select(pair => pair.index)
                        .First();

这应该是好的,只要列表不包含long.MaxValue + 1元素,它不能在当前版本的。net。(这是很大的内存……)老实说,当它超出int.MaxValue元素时,由于Select部分采用int索引,这已经有问题了…

list.Sort();
var range = Enumerable.Range( list.First(), list.Last()- list.First());
var number = range.Except(list).FirstOrDefault();