OJ链接——错误的集合

本文介绍了如何在C语言中处理一个集合数据错误问题,通过两种方法寻找重复的整数和丢失的整数:一种是逐个比较的时间复杂度较大的方法,另一种是利用标记法优化时间效率。
摘要由CSDN通过智能技术生成

  • 更多C语言的练习题可以点这个链接——C语言练习

1. 题目

1.1 题目描述

  • 集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复
  • 给定一个数组 nums 代表了集合 S 发生错误后的结果。
  • 请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。

1.2 示例

在这里插入图片描述
在这里插入图片描述

2. 分析

2.1 思路1

2.1.1 分析

  • 我们可以定义 i 和 j 来逐个比较

在这里插入图片描述

  • 当比较的两个数字不相等的时候,就继续往后
  • 直到两个数相等的时候停止,那么此时不管是 i 指向的地方还是 j 指向的地方都是重复的数字,

在这里插入图片描述

  • 接着我们怎么求被覆盖的数字是多少呢
  • 我们可以先把重复的数字去掉一个,接着把数组的每个元素加起来,记为sum1
  • 接着再把原来没有重复的数组求和,记为sum2
  • 最后sum2-sum1就是被覆盖掉的数字了

2.1.2 完整代码

static int arr[2] = {0};

int* findErrorNums(int* nums, int numsSize, int* returnSize) 
{
        int c = 0;
        int flag = 1;
        int sum1 = 0;
        int sum2 = 0;
        
        for (int i=0; i<numsSize-1; i++)
        {
            for (int j=i+1; j<numsSize; j++)
            {
                if (*(nums+i) == *(nums+j))
                {
                    flag = 0;
                    c = *(nums+i);
                    break;
                }//i和j对应的数字是否相等
            }
            
            if (flag == 0)
            {
                break;
            }
        }
        
        for (int i=0; i<numsSize; i++)
        {
            sum1 += i+1;
            sum2 += *(nums+i);
        }//分别求和
        
        arr[0] = c;//重复的数字
        arr[1] = sum1-(sum2-c);//被覆盖的数字
        *returnSize = 2;
        return arr;
}
  • 运行结果:

在这里插入图片描述

  • 我们可以看到这样做思路虽然清晰,但是时间复杂度是比较大的
  • 那么有没有更快的呢

2.2 思路2

2.2.1 分析

  • 使用标记的方法
  • 首先把数组都遍历一次,在此过程中记录每个数字出现的次数,如果哪个数字出现次数为2,则为重复的数字
  • 如果有的数字出现次数为0,则为丢失的数字

2.2.2 完整代码

int* findErrorNums(int* nums, int numsSize, int* returnSize)
{

    int* arr = (int*)malloc(sizeof(int) * (numsSize+1));//开辟标记的空间
    memset(arr, 0, sizeof(int) * (numsSize+1));//初始化
    int* num = (int*)malloc(sizeof(int) * 2);//开辟最后结果的空间

    for (int i = 0; i < numsSize; i++)
    {
        arr[nums[i]] += 1;
    }//开始标记

    for (int j = 1; j < numsSize+1; j++)
    {
        if (arr[j] == 2)
        {
            num[0] = j;
        }
        else if (arr[j] == 0)
        {
            num[1] = j;
        }
    }//查看标记
    
    *returnSize = 2;
    return num;
}
  • 运行结果:

在这里插入图片描述

最后,
恭喜你又遥遥领先了别人!!
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

看落日的YT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值