前言:本期是关于力扣-错误的集合的详解,今天你c了吗?
题目:
集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。
给定一个数组 nums 代表了集合 S 发生错误后的结果。
请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
示例 1:
输入:nums = [1,2,2,4]
输出:[2,3]
示例 2:
输入:nums = [1,1]
输出:[1,2]
代码实现:
int* findErrorNums(int* nums, int numsSize, int* returnSize)
{
*returnSize=2;
int*arr=(int*)calloc(numsSize+1,sizeof(int));
int*ret=(int*)calloc(*returnSize,sizeof(int));
int i=0;
int original_sum=0;
int current_sum=0;
for(i=0;i<numsSize;i++)
{
if(arr[nums[i]]==1)
{
ret[0]=nums[i];
}
arr[nums[i]]=1;
original_sum+=i+1;
current_sum+=nums[i];
}
ret[1]=original_sum-(current_sum-ret[0]);
free(arr);
return ret;
}
大致思路:
1. calloc申请numsSize+1个大小的空间,为了让已有的数组中的数字作为arr数组的下标
eg :1 2 2 4 我们需要有下标4 ,故而需要创建5个空间
2. 寻找重复数字:
遍历已有数组,将已有数组中的数字作为arr数组的下标,在对应的arr数组的空间内置1
注意:将下标对应的arr数组空间内置1的前提是,这块空间原本没有1
若是遍历到某个已有数组空间的数字时,发现其作为下标所对应的arr数组空间内有了1
则表示此数字是重复数字
3. 寻找丢失数字
题目告知:集合 s
包含从 1
到 n
的整数,故而我们可以使用:
a.下标累加来求出原有和
b. 已有数组中的数字相加求出现有和
c. 原有和-(现有和-重复数字)=丢失数字
eg. 1 2 2 4
下标累加求原有和: 下标+1才是对应的已有数组中的数字
1 | 2 | 2 | 4 |
下标: | |||
0 | 1 | 2 | 3 |
下标累加: | |||
原有和(0+1)+ (1+1)+(2+1)+ (3+1)=1+2+3+4 |
已有数组中的数字相加求现有和 :
1 | 2 | 2 | 4 |
现有和 1+2+2+4 减去重复数字:1+2+4 丢失数字:(1+2+3+4)-(1+2+4)= 3 |
代码解读:
part 1
*returnSize=2;
int*arr=(int*)calloc(numsSize+1,sizeof(int));
int*ret=(int*)calloc(*returnSize,sizeof(int));
使用calloc需要包含头文件:
#include <stdlib.h> |
calloc申请动态空间arr数组:
若是已有数组中的数字是第一次出现,则其作为下标所对应的arr数组中的某块空间就会存放1
calloc申请动态空间ret数组:
用于存放重复的数字和丢失的数字
part 2
int i=0;
int original_sum=0;
int current_sum=0;
for(i=0;i<numsSize;i++)
{
if(arr[nums[i]]==1)
{
ret[0]=nums[i];
}
arr[nums[i]]=1;
original_sum+=i+1;
current_sum+=nums[i];
}
ret[1]=original_sum-(current_sum-ret[0]);
free(arr);
return ret;
1. for循环遍历已有数组,若是已有数组中的数字作为下标,其对应的arr数组的某块空间内放置了1 ,则说明此数字就是重复的数字,存入ret数组的第一个空间里
2. 其对应的arr数组的某块空间内没有放置1,则表示此数字是第一次出现,不是重复数字
将此数字作为下标,它所对应的arr数组中的某块空间置1
3. 原有和:
每个下标+1后累加
现有和:
已有数组中的数字累加
4. 丢失数字=原有和-(现有和-重复数字)存入ret数组中的第二块空间
5. 释放arr数组空间