题目链接:645. 错误的集合 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/set-mismatch/
题目描述:集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。
给定一个数组 nums 代表了集合 S 发生错误后的结果。
请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
示例 1:
输入:nums = [1,2,2,4]
输出:[2,3]
法一:排序
(1)先把nums数组按升序排序,然后比较相邻两个元素,如果相等,则找到重复元素
(2)找到丢失的元素比较麻烦,如果丢失的这个数是大于1小于n的,由于数组已经排序,则一定存在两个相邻的数字的差值为2,则丢失的数字在两个相邻数字的中间
比如1,2,2,4,我们可以看到2和4是相差2,,则丢失的数字是2和4之间也就是3
当丢失的数字是1时,我们一开始需要把上一个元素初始化为0,比如用lastone标记上一个元素,数组是2,2,我们可以看到重复数字是2,丢失是1,一开始用cur标记第一个2,然后cur-lastone>1因为cur=2,lastone一开始是被初始化为0的,所以丢失的数字是lastone+1;也就是1
代码:
int cmp(int* a, int* b) {
return *a - *b;
}
int* findErrorNums(int* nums, int numsSize, int* returnSize) {
int* ret = malloc(sizeof(int) * 2);
*returnSize = 2;
qsort(nums, numsSize, sizeof(int), cmp);
int lastone = 0;
for (int i = 0; i < numsSize; i++) {
int cur = nums[i];
if (cur == lastone) {
ret[0] = lastone;
} else if (cur -lastone > 1) {
ret[1] = lastone + 1;
}
lastone = cur;
}
if(nums[numsSize-1]!=numsSize)
ret[1]=numsSize;
return ret;
}
法二:哈希表
以1,2,2,4为例,我们例外设一个5长度的数组int arr[5],然后因为是1到n的数字,就把1到n作为下标,放到arr里并标记为1,也就是arr[nums[i]]=1,到最后2,2会被重复标记为1,则我们找到重复数字2,
然后将1加到n减去当前数组数据总和再加重复数字,就是丢失的数字
以上面1,2,2,4为例就是:
(1+2+3+4)-(1+2+2+4)+2=3
代码如下:
int* findErrorNums(int* nums, int numsSize, int* returnSize)
{
*returnSize=2;
int*ret=(int*)calloc(*returnSize,sizeof(int));
int*arr=(int*)calloc(numsSize+1,sizeof(int));
int old_sum=0,cur_sum=0,i=0;
for(i=0;i<numsSize;i++)
{
if(arr[nums[i]]==1)
{
ret[0]=nums[i];
}
arr[nums[i]]=1;
old_sum+=i+1;
cur_sum+=nums[i];
}
ret[1]=old_sum-(cur_sum-ret[0]);
free(arr);
return ret;
}