当前位置 博文首页 > Inmaturity_7的博客:算法练习贴--73--错误的集合(C语言)
集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。
给定一个数组 nums 代表了集合 S 发生错误后的结果。
请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
(题目来源:力扣(LeetCode))
示例 1:
输入:nums = [1,2,2,4]
输出:[2,3]
示例 2:
输入:nums = [1,1]
输出:[1,2]
提示:
2 <= nums.length <= 104
1 <= nums[i] <= 104
1. 位运算
int* findErrorNums(int* nums, int numsSize, int* returnSize) {
int* errorNums = malloc(sizeof(int) * 2);//存储结果数组
int xorSum = 0;//缺失数和多余数
for (int i = 1; i <= numsSize; i++) {
//分别异或1到numsSize以及数组中的值
//由于缺失的数数量为1,多余的数数量为3
//于是异或完之后xorSum=缺失数^多余数
xorSum ^= i;
xorSum ^= nums[i - 1];
}
//下面是将这两个数分离开来
int lowbit = xorSum & (-xorSum);//获取这两个数二进制位第一个不同的位(从低位到高位,这两个数位不同时在xorSum对应肯定为1)
int num1 = 0, num2 = 0;//丢失数和多余数
//下面相当于分组异或
//多余数和丢失数肯定lowbit(因为多余数和丢失数在此位一个为0,另一个为1)分开来
for (int i = 0; i < numsSize; i++) {
if ((nums[i] & lowbit) == 0) {
num1 ^= nums[i];
} else {
num2 ^= nums[i];
}
}
for (int i = 1; i <= numsSize; i++) {
if ((i & lowbit) == 0) {
num1 ^= i;
} else {
num2 ^= i;
}
}
//异或完之后,num1和num2就是丢失数和多余数(但是哪个是哪个还不清楚)
int* ret = malloc(sizeof(int) * 2);
*returnSize = 2;
for (int i = 0; i < numsSize; i++) {//再原数组中搜索这个数,搜索到便是多余数,没搜索到便是丢失数
if (nums[i] == num1) {
ret[0] = num1, ret[1] = num2;
return ret;
}
}
ret[0] = num2, ret[1] = num1;
return ret;
}
2.计数法
int* findErrorNums(int* nums, int numsSize, int* returnSize){
int *count=(int*)malloc(sizeof(int)*(numsSize+1)),i,*ans=(int*)malloc(sizeof(int)*2),flag1=0,flag2=0;
memset(count,0,sizeof(int)*(numsSize+1));//数组元素全部赋值为0
*returnSize=2;
for(i=0;i<numsSize;i++)
count[nums[i]]++;//统计数组对应元素的数量
for(i=1;i<=numsSize;i++)
{
if(flag1&&flag2)//这两个flag是分别标记两个数找到没
break;
if(count[i]>1)
{//如果大于1个说明是多余数
ans[0]=i;
flag1=1;
}
if(count[i]==0)
{//如果个数等于0说明时丢失数
ans[1]=i;
flag2=0;
}
}
return ans;
}
cs