力扣:剑指 Offer 03. 数组中重复的数字(c语言详解)

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

题目:

找出数组中重复的数字。


在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

示例 1:

输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3 

代码实现:

int findRepeatNumber(int* nums, int numsSize)
{
    int i = 0;
    for(i=0;i<numsSize;i++)
    {
        if(nums[i]!=i)
        {
            if(nums[nums[i]]!=nums[i])
            {
                int tmp = nums[i];
                nums[i]=nums[tmp];
                nums[tmp]=tmp;
                i--;
            }
            else
            {
                return nums[i];
            }
        }
    }
    return -1;
}

大致思路: 

采用原数字修改的方法:

遍历整个数组:

1 若是下标值和此下标所对应的空间中的数值相等(专业对口),则跳过当前空间,判断下一个空间

可以想象成专业对口:arr[0]的岗位上若是0,则专业对口,就跳过这个岗位去判断下一个岗位是否专业对口,若不是0,则需要找到与岗位arr[0]专业对口的人

2 若是不相等(专业不对口),则以这个A空间中的值为下标,找到另一块B空间,并判断在B空间中是否已经有了专业对口的人(下标值和它对应的空间中的值相等),若是已经有了,则此下标就是重复的数字,返回它的值,若是没有,则交换A,B两个空间中的值

3 若是交换两个空间中的值后需要i--,因为马上要执行的语句是i++,这样做的效果是先退后一步,再前进一步==原地不动,因此可以再次对arr[i] 进行判断是否专业对口(即下标值=对应空间中的数值)

4 若是整个循环结束后都没有返回,则说明找不到重复数字,返回-1

比如:

2310253
下标0 123456

遍历整个数组,i刚开始是0 

a .arr[0]=2 与下标0的值不等:专业不对口

b. arr[2]=1 并且 1和下标2不等:交换arr[0]和arr[2]-> arr[0]=1 arr[2]=2

1320253
下标0 123456

c 由于发生交换,则i--,i=-1,由于下一步是i++(马上要遍历到第二个元素),故而i最终还是0

   接着判断arr[0]是否专业对口,arr[0]=1 ,专业不对口,则:重复b,c

   arr[1]=3 专业不对口,交换arr[0]和arr[1]->arr[0]=3 arr[1]=1

3120253
下标0 123456

   由于发生交换,则i--,又i++,最终i=0

 判断arr[0]是否专业对口,arr[0]=3,专业不对口,则:重复b,c

arr[3]=0 专业不对口,交换arr[0]和arr[3]->arr[0]=0 arr[3]=3

0123253
下标0 123456

 i--,i++,i=0,判断arr[0]是否专业对口,arr[0]=0,专业对口,则i++,找下一个空间,判断它是否专业对口:找到下标i=1的空间

arr[1]=1,专业对口,i++, i=2,找下一个空间判断:arr[2]=2,专业对口,i++,i=3,找下一个空间判断:arr[3]=3,专业对口,i++,i=4,找下一个空间判断:arr[4]=2,专业不对口,又arr[2]=2,已经专业对口了,则2是重复数字,返回它

代码解读:

int findRepeatNumber(int* nums, int numsSize)
{
    int i = 0;
    for(i=0;i<numsSize;i++)//遍历数组
    {
        if(nums[i]!=i)//专业不对口
        {
            if(nums[nums[i]]!=nums[i])另一个空间也专业不对口则交换
            {
                int tmp = nums[i];
                nums[i]=nums[tmp];
                nums[tmp]=tmp;
                i--;
            }
            else//另一个空间已经专业对口
            {
                return nums[i];//此数为重复数字,返回
            }
        }
    }
    return -1;//找不到重复数字
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值