力扣:找到数组中所有消失的数字(详解)

前言:内容包括四大模块:题目,代码实现,大致思路,代码解读

 题目:

给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。

示例 1:

输入:nums = [4,3,2,7,8,2,3,1]
输出:[5,6]
示例 2:

输入:nums = [1,1]
输出:[2]

代码实现:

int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize)
{
    int i = 0;
    int *ret=(int *)calloc(numsSize,sizeof(int));
    *returnSize=0;
    for(i=0; i<numsSize; i++)
    {
        if(nums[abs(nums[i])-1]>0)
        {
            nums[abs(nums[i])-1]=-nums[abs(nums[i])-1];
        }
    }
    for(i=0; i<numsSize; i++)
    {
        if(nums[i]>0)
        {
            ret[(*returnSize)++]=i+1;
        }
    }
    return ret;
}

大致思路:

以数组[2, 3, 3, 2, 4]为例:

原本完整的数组是1 2 3 4 5  现缺少了1和5

数组中有2,则一定会有下标1(2-1=1),数组中有3,则一定会有下标2(3-1=2)依次类推

我们将数组中已有元素的绝对值-1作为新的下标,将其对应的元素置为负数

若是数组中缺失的元素,则其绝对值-1的新下标所对应的元素不会置为负数,仍是正数形式

故而思路:

1.遍历数组,将数组中元素绝对值-1作为新的下标,将新下标所对应的数组元素置为负数

    注意:要置成负数的元素它必须是正数,不能是负数

 2. 若是置换结束后,发现数组中仍有元素是正数,则缺失的数字即为此元素下标+1

演示:[2, 3, 3, 2, 4]

第一个元素是2,将下标为1(2-1)的元素置为负数,数组变成:[2, -3, 3, 2, 4]

第二个元素是-3,用-3的绝对值-1作为新下标,将新下标2所对应的元素置为负数:[2, -3, -3, 2, 4]

第三个元素是-3,新下标:2,本来应该是要将下标为2的元素置为负数,但是不能进行置换,否则负负得正,我们要置为负数的元素,它本身必须是正数,不能是负数

第四个元素是2,新下标:1,由于下标1对应的元素不是正数,故不置为负数

第五个元素是4,新下标:3,将下标为3的元素置为负数:[2, -3, -3, -2, 4]

置换完毕,再遍历数组查找数组中仍为正数的元素:2和4

2的下标是0,故而缺少了元素1

4的下标是4,故而缺少了元素5

代码解读:

part 1:申请空间

int *ret=(int *)calloc(numsSize,sizeof(int));

使用calloc函数动态申请numsSize个大小为int类型的空间,地址存储到ret中

part 2:找出所有的消失数字

    

    for(i=0; i<numsSize; i++)
    {
        if(nums[abs(nums[i])-1]>0)
        {
            nums[abs(nums[i])-1]=-nums[abs(nums[i])-1];
        }
    }

1. 遍历整个数组中的元素

    将数组中元素绝对值-1的值作为新下标,对应原有数组

2.  for循环内部:

    若是当前元素绝对值-1的新下标所对应的原数组元素是正数,则将其置为负数

    当for循环结束后,只有消失数字的绝对值-1的新下标所对应的元素是正数

    part 3

    for(i=0; i<numsSize; i++)
    {
        if(nums[i]>0)
        {
            ret[(*returnSize)++]=i+1;
        }
    }

遍历整个数组,找出数组中仍为正数的数字

缺失的数字就是此正数下标+1

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值