做题博客链接
https://blog.csdn.net/qq_43349112/article/details/108542248
题目链接
https://leetcode-cn.com/problems/set-mismatch/
描述
集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一
个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。
给定一个数组 nums 代表了集合 S 发生错误后的结果。
请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
提示:
2 <= nums.length <= 104
1 <= nums[i] <= 104
示例
示例 1:
输入:nums = [1,2,2,4]
输出:[2,3]
示例 2:
输入:nums = [1,1]
输出:[1,2]
初始代码模板
class Solution {
public int[] findErrorNums(int[] nums) {
}
}
代码
推荐题解:
https://leetcode-cn.com/problems/set-mismatch/solution/cuo-wu-de-ji-he-by-leetcode/
1.使用额外空间
class Solution {
public int[] findErrorNums(int[] nums) {
boolean[] vis = new boolean[nums.length + 1];
int a = 0;
for (int i = 0; i < nums.length; i++) {
if (vis[nums[i]]) {
a = nums[i];
}
vis[nums[i]] = true;
}
for (int i = 1; i < vis.length; i++) {
if (!vis[i]) {
return new int[]{a, i};
}
}
return null;
}
}
2.原数组上进行更改
class Solution {
public int[] findErrorNums(int[] nums) {
int dul = -1;
int mis = -1;
for (int num : nums) {
//num本身可能是负的,因为前面被修改掉了,所以要用绝对值
num = Math.abs(num);
if (nums[num - 1] < 0) {
dul = num;
}
nums[num - 1] = -nums[num - 1];
}
for (int i = 0; i < nums.length; i++) {
if (nums[i] > 0 && i + 1 != dul) {
mis = i + 1;
}
}
return new int[]{dul, mis};
}
}
3.位运算
class Solution {
public int[] findErrorNums(int[] nums) {
int xor = 0;
int a = 0;
int b = 0;
for (int num : nums) {
xor ^= num;
}
for (int i = 1; i <= nums.length; i++) {
xor ^= i;
}
//根据最后一个1进行分组
int bit = xor & ~(xor - 1);
for (int num : nums) {
if ((bit & num) != 0) {
a ^= num;
} else {
b ^= num;
}
}
for (int i = 1; i <= nums.length; i++) {
if ((bit & i) != 0) {
a ^= i;
} else {
b ^= i;
}
}
//因为不清楚a、b哪个是多的,哪个是缺的,需要进行筛选
for (int num : nums) {
if (num == a) {
return new int[]{a, b};
}
}
return new int[]{b, a};
}
}