问题描述
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.
Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
题目描述
给定一个长度为n的数组,这个数组中数的区间是[0,n+1]。要求找出少了的哪个数。
要求只能用常量的空间,以及O(n)的时间复杂度。
解法使用一个标志位表示第n+1的数在系统中是否出现过。然后前面n个数用数组本身来表示。遍历每一个数,把这个数对应位置的数设置为负数。然后判断一下大于0的数就是不出现的。但是会 有问题,0表示的出现在的哪个位置的数没有办法知道是否出现。所以最终判断的时候,就是如果存在>0的哪个数就是没有出现的,如果没有,那么就是0的哪个数。
代码实现
/**
* 找出消失的数
*
* @param nums
* @return
*/
public int missingNumber(int[] nums) {
if (nums == null || nums.length == 0) {
return -1;
}
int zeroIndex = -1;
int nFlag = 1;
for (int i = 0; i < nums.length; i++) {
int num = Math.abs(nums[i]);
if (num == nums.length) {
nFlag = -1;
} else {
nums[num] = -1 * nums[num];
}
}
if (nFlag > 0) {
return nums.length;
}
for (int i = 0; i < nums.length; i++) {
if (nums[i] > 0) {//如果>0表示没有出现
return i;
} else if (nums[i] == 0) {
zeroIndex = i;//否者0就是可能的数。
}
}
return zeroIndex;
}
解法二
可以利用异或的特性 a = a^b^b。如果一个数同时异或一个数两次,那么这个数还是原来的数。这样就好办了。把数组中的n个数异或一下,然后和0~n+1都异或。最终得到的哪个值就是只出现一次的值。0和任何数异或都是任何数。
/**
* 找出消失的数
*
* @param nums
* @return
*/
public int missingNumber(int[] nums) {
int xor = 0;
for (int i = 0; i < nums.length; i++) {
xor = xor ^ i ^ nums[i];
}
return xor ^ nums.length;
}