题目大意
给定一个包含 0, 1, 2, ..., n 中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。
示例1:
输入: [3,0,1]
输出: 2
示例2:
输入: [9,6,4,2,3,5,7,0,1]
输出: 8
说明:
你的算法应具有线性时间复杂度。你能否仅使用额外常数空间来实现?
方法一:排序
public int missingNumber(int[] nums) {
Arrays.sort(nums);
for(int i=0;i<nums.length;i++)
if(nums[i]!=i) return i;
return nums.length;
}
运行时间17ms,击败17.10%。
方法二:数组存储访问
public int missingNumber(int[] nums) {
int[] visit = new int[nums.length+1];
for(int i=0;i<nums.length;i++)
visit[nums[i]]=1;
for(int i=0;i<nums.length;i++)
if(visit[i]==0) return i;
return nums.length;
}
运行时间3ms,击败43.28%。
方法三:数学方法
利用高斯公式,先计算出0-n的和,然后减去num数组中的每一个数。
public int missingNumber(int[] nums) {
int res = (1+nums.length)*nums.length/2;
for(int i=0;i<nums.length;i++)
res -= nums[i];
return res;
}
运行时间2ms,击败91.02%。
方法四:位运算
一个数与它本身异或得到0。
public int missingNumber(int[] nums) {
int res = 0;
for(int i=1;i<=nums.length;i++)
res ^= i;
for(int i=0;i<nums.length;i++)
res = res ^ nums[i];
return res;
}
改进版本:
public int missingNumber(int[] nums) {
int res = nums.length;
for(int i=0;i<nums.length;i++)
res ^= i ^ nums[i];
return res;
}
运行时间2ms,击败91.02%。