如果只有 1 个缺失值,则意味着您具有以下条件:
- 文件包含从最低值
N
到最高值(包括最高值)的所有数字,其中M
1 个除外。
- 文件不必排序
- 这些值中只有 1 个缺失(只是确保)
那么解决方案就很简单了:
将文件中的所有数字相加或异或。
将您应该拥有的所有数字相加或异或。
缺少的数字要么是一个减去另一个(在 ADD 的情况下),要么是一个异或另一个。
这是一个您可以试验的LINQPad程序:
void Main()
{
var input = new[] { 1, 2, 3, 4, 5, 6, 8, 9, 10 };
var lowest = input[0];
var highest = input[0];
int xor = 0;
foreach (var value in input)
{
lowest = Math.Min(lowest, value);
highest = Math.Max(highest, value);
xor ^= value;
}
int requiredXor = 0;
for (int index = lowest; index <= highest; index++)
requiredXor ^= index;
var missing = xor ^ requiredXor;
missing.Dump();
}
基本上,它将:
- 异或文件中的所有值(值 1)
- 同时找到最低和最高的数字
- 从最低到最高对所有值进行异或(值 2)
- 将两个值(值 1 和值 2)异或在一起以找到缺失值
此方法不会检测缺失值是最小值 - 1 还是最大值 + 1,例如,如果文件应该保存 1..10,但缺少 10 或 1,则上述方法将找不到它。
这个解决方案是 O(2n)(我们将数字循环两次),转换为 O(n)。
这是一个更完整的示例,显示了 ADD 和 XOR 解决方案(同样在 LINQPad 中):
void Main()
{
var input = new[] { 1, 2, 3, 4, 5, 6, 8, 9, 10 };
MissingXOR(input).Dump("xor");
MissingADD(input).Dump("add");
}
public static int MissingXOR(int[] input)
{
var lowest = input[0];
var highest = input[0];
int xor = 0;
foreach (var value in input)
{
lowest = Math.Min(lowest, value);
highest = Math.Max(highest, value);
xor ^= value;
}
int requiredXor = 0;
for (int index = lowest; index <= highest; index++)
requiredXor ^= index;
return xor ^ requiredXor;
}
public static int MissingADD(int[] input)
{
var lowest = input[0];
var highest = input[0];
int sum = 0;
foreach (var value in input)
{
lowest = Math.Min(lowest, value);
highest = Math.Max(highest, value);
sum += value;
}
var sumToHighest = (highest * (highest + 1)) / 2;
var sumToJustBelowLowest = (lowest * (lowest - 1)) / 2;
int requiredSum = sumToHighest - sumToJustBelowLowest;
return requiredSum - sum;
}