集合 s
包含从 1
到 n
的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。
给定一个数组 nums
代表了集合 S
发生错误后的结果。
请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
示例 1:
输入:nums = [1,2,2,4] 输出:[2,3]
示例 2:
输入:nums = [1,1] 输出:[1,2]
提示:
2 <= nums.length <= 104
1 <= nums[i] <= 104
首先使用 1 到 n 的所有数字做异或运算,然后再与数组中的所有数字异或,得到的值就是缺失数字与重复的数字异或的结果。
接着计算中这个值中其中一个非零的位 pos。然后 pos 位是否为 1,将 nums 数组的元素分成两部分,分别异或;接着将 1~n
的元素也分成两部分,分别异或。得到的两部分结果分别为 a,b,即是缺失数字与重复数字。
最后判断数组中是否存在 a 或 b,若存在 a,说明重复数字是 a,返回 [a,b]
,否则返回 [b,a]
。
class Solution:
def findErrorNums(self, nums: List[int]) -> List[int]:
res = 0
for num in nums:
res ^= num
for i in range(1, len(nums) + 1):
res ^= i
pos = 0
while (res & 1) == 0:
res >>= 1
pos += 1
a = b = 0
for num in nums:
if ((num >> pos) & 1) == 0:
a ^= num
else:
b ^= num
for i in range(1, len(nums) + 1):
if ((i >> pos) & 1) == 0:
a ^= i
else:
b ^= i
for num in nums:
if num == a:
return [a, b]
return [b, a]
class Solution {
public int[] findErrorNums(int[] nums) {
int res = 0;
for (int num : nums) {
res ^= num;
}
for (int i = 1, n = nums.length; i < n + 1; ++i) {
res ^= i;
}
int pos = 0;
while ((res & 1) == 0) {
res >>= 1;
++pos;
}
int a = 0, b = 0;
for (int num : nums) {
if (((num >> pos) & 1) == 0) {
a ^= num;
} else {
b ^= num;
}
}
for (int i = 1, n = nums.length; i < n + 1; ++i) {
if (((i >> pos) & 1) == 0) {
a ^= i;
} else {
b ^= i;
}
}
for (int num : nums) {
if (num == a) {
return new int[]{a, b};
}
}
return new int[]{b, a};
}
}