The Second One

博主新开了第二个博客,旨在进行专业上的积累学习。
这是我开的第二博客,回很好在专业上进行积累学习。 
<think>题目要求:找出第一个只出现一次的数字。如果没有这样的数字,输出"None"。 思路: 1. 读取输入,第一个整数是N,后面跟着N个数字。 2. 我们需要记录每个数字出现的次数,同时还要记录每个数字第一次出现的顺序(因为要按输入顺序找到第一个唯一的)。 3. 由于数字范围是[1, 10000],所以我们可以用一个数组count来统计每个数字出现的次数。 4. 但是,我们还需要知道每个数字第一次出现的位置(或者顺序),这样当遍历输入序列时,我们可以按顺序检查哪个数字是唯一的(即出现次数为1),并且是第一个出现的唯一数字。 具体步骤: 方法一: - 使用两个数组:一个数组`count`记录每个数字出现的次数,另一个数组`firstIndex`记录每个数字第一次出现的索引(在输入序列中的位置)。 - 然后我们遍历所有输入数字,对于每个数字,如果它的出现次数为1,我们就记录它第一次出现的位置(索引),然后我们找到所有唯一数字中索引最小的那个。 - 但是注意:题目要求的是第一个唯一的数字,也就是在输入序列中第一个出现并且只出现一次的数字。所以我们可以这样: a. 遍历输入序列,同时记录每个数字出现的次数和它第一次出现的位置(索引)。 b. 然后再次遍历输入序列(按顺序),检查当前数字出现的次数是否为1,第一个遇到的次数为1的数字就是答案。 方法二(更简单): - 我们只需要记录每个数字出现的次数。 - 然后按输入顺序遍历数字,对于每个数字,检查其出现次数是否为1,第一个遇到的次数为1的数字就是答案,输出并结束。 - 如果遍历完都没有,则输出"None"。 注意:数字范围是[1,10000],所以数组大小可以设为10001(索引0不用,或者用0-10000)。 输入的数字个数N最多为10^5,所以我们可以用数组计数。 步骤: 1. 读取第一个整数N。 2. 动态分配一个数组存储N个数字(或者直接定义一个数组,大小100000),并读取接下来的N个数字。 3. 初始化一个计数数组count,大小为10001(索引0到10000),初始化为0。 4. 第一次遍历:遍历输入的N个数字,对每个数字,增加计数。 5. 第二次遍历:再次遍历输入的N个数字,对于每个数字,如果它的计数为1,则输出这个数字并结束遍历。 6. 如果第二次遍历没有找到任何计数为1的数字,则输出"None"。 注意:题目要求的是第一个唯一的数字,所以第二次遍历按输入顺序,找到的第一个出现次数为1的数字就是答案。 例如样例1:7 5 31 5 88 67 88 17 计数:5:2, 31:1, 88:2, 67:1, 17:1 按顺序遍历:5出现2次(跳过),31出现1次(输出31,结束)。 样例2:5 888 666 666 888 888 计数:888:3, 666:2 按顺序:888(3次,跳过),666(2次,跳过),再888(跳过),888(跳过),没有唯一,输出None。 代码实现: 注意:数字范围是[1,10000],所以计数数组大小设为10001(索引0不用,1~10000)。 但是注意:输入的数字可能超出这个范围吗?题目说“one bets on a number chosen from [1, 104]”,这里104应该是10^4,即10000。所以数字在1到10000之间。 所以,我们可以安全地使用数组。 代码:</think>### 解决方案:寻找第一个唯一数字 #### 算法思路 要找到第一个只出现一次的数字(即唯一数字),需要: 1. **统计频率**:记录每个数字出现的次数 2. **顺序查找**:按输入顺序查找第一个出现次数为1的数字 3. **处理边界**:若无唯一数字则输出"None" #### C语言实现 ```c #include <stdio.h> #include <stdlib.h> #define MAX_N 100000 #define MAX_NUM 10000 int main() { int n; // 处理多组输入直到文件结束 while (scanf("%d", &n) != EOF) { int *bets = (int *)malloc(n * sizeof(int)); int count[MAX_NUM + 1] = {0}; // 初始化计数数组(索引0-10000) // 读取投注数字并统计频率 for (int i = 0; i < n; i++) { scanf("%d", &bets[i]); if (bets[i] >= 1 && bets[i] <= MAX_NUM) { count[bets[i]]++; } } int winner = -1; // 初始化获胜数字为-1(未找到) // 按输入顺序查找第一个唯一数字 for (int i = 0; i < n; i++) { if (count[bets[i]] == 1) { winner = bets[i]; break; // 找到后立即退出循环 } } // 输出结果 if (winner != -1) { printf("%d\n", winner); } else { printf("None\n"); } free(bets); // 释放动态分配的内存 } return 0; } ``` #### 代码解释 1. **输入处理**: - `while (scanf("%d", &n) != EOF)` 循环读取多组测试数据 - 动态分配数组`bets`存储投注数字 2. **频率统计**: - 创建计数数组`count`(大小10001),初始化为0 - 遍历输入数字,对有效数字(1-10000)进行计数 3. **查找唯一数字**: - 按输入顺序遍历数字 - 当找到第一个计数为1的数字时,立即记录并跳出循环 4. **结果输出**: - 找到有效数字时输出该数字 - 未找到时输出"None" - 释放动态分配的内存 #### 样例验证 1. **输入"7 5 31 5 88 67 88 17"**: - 频率统计:5(2), 31(1), 88(2), 67(1), 17(1) - 顺序查找:31是第一个唯一数字 → 输出"31" 2. **输入"5 888 666 666 888 888"**: - 频率统计:888(3), 666(2) - 无唯一数字 → 输出"None" #### 算法特性 - **时间复杂度**:O(n) 两次线性遍历 - **空间复杂度**:O(n + MAX_NUM) 存储输入和计数数组 - **正确性保证**: - 频率统计确保准确计数 - 顺序查找保证找到第一个唯一数字 --- ### 相关问题
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值