Given an array containing n distinct numbers taken from 0, 1, 2, ..., n
, find the one that is missing from the array.
For example,
Given nums = [0, 1, 3]
return 2
.
给定一个包含从0, 1, 2, ..., n, 选出的n个不同数字的数组,从中找出数组中缺失的那一个数。
Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
注意:
你的算法应该满足线性时间复杂度。你可以只使用常数空间复杂度完成此题吗?
思路:等差数列前n项和 - 数组之和
static public int MissingNumber(int[] nums) {
if (nums.Length == 0) {
return 0;
}
int max = 0;
int min = Int32.MaxValue;
int total = 0;
foreach (int i in nums) {
total += i;
min = i < min ? i : min;
max = i > max ? i : max;
}
int rest = max * (max + 1) / 2 - total;
if (min == 0) {
return (rest == 0) ? max + 1 : rest;
} else {
return min - 1;
}
}
他山之石:
从CPU指令所耗费的时钟周期来看,比加法更高效率的运算是异或(XOR)运算。本题的标签里有位运算,暗示本题可以用位运算的方法解决。
异或运算的一个重要性质是,相同的数异或得0,不同的数异或不为0,且此性质可以推广到多个数异或的情形。本题的解法如下,首先将0到n这些数进行异或运算,然后对输入的数组进行异或运算,最后将两个结果进行异或运算,结果便是漏掉的数字,因为其他数字在两个数组中都是成对出现的,异或运算会得到0。
class Solution {
public:
int missingNumber(vector<int>& nums) {
int x = 0;
for (int i = 0; i <= nums.size(); i++) x ^= i;
for (auto n : nums) x ^= n;
return x;
}
};