LeetCode 136. 只出现一次的数字(C语言详解 | 哈希表 + 排序 + 位运算)

一、题目描述

给你一个 非空整数数组 nums ,除了某个元素 只出现一次 以外,其余每个元素均 出现两次。请找出那个只出现了一次的元素。

要求:

  • 时间复杂度 O(n)

  • 空间复杂度 O(1)

示例 1

复制代码
输入:nums = [2,2,1]
输出:1

示例 2

复制代码
输入:nums = [4,1,2,1,2]
输出:4

示例 3

复制代码
输入:nums = [1]
输出:1

提示

复制代码
1 <= nums.length <= 3 * 10^4
-3 * 10^4 <= nums[i] <= 3 * 10^4

二、解题思路

本题核心特点:

  • 只有一个数字出现一次

  • 其他数字都出现两次

可以从三个方向解决:

1️⃣ 哈希表统计次数

2️⃣ 排序后成对查找

3️⃣ 位运算(最优解)

下面逐一介绍。


三、解法一:哈希表

思路

使用哈希表统计每个数字出现的次数:

  1. 遍历数组

  2. 统计每个数字出现次数

  3. 找到出现一次的数字

由于题目范围为:

复制代码
-30000 ~ 30000

可以直接用 数组模拟哈希表


C语言代码

复制代码
#include <stdlib.h>

int singleNumber(int* nums, int numsSize) {
    
    int offset = 30000;
    int hash[60001] = {0};
    
    for(int i = 0; i < numsSize; i++)
    {
        hash[nums[i] + offset]++;
    }
    
    for(int i = 0; i < 60001; i++)
    {
        if(hash[i] == 1)
            return i - offset;
    }
    
    return 0;
}

复杂度分析

复制代码
时间复杂度:O(n)
空间复杂度:O(n)

缺点:不满足题目 常量空间要求


四、解法二:排序

思路

先排序,然后每两个元素检查一次:

复制代码
1 1 2 2 4
      ↑

如果某个元素 和相邻元素不同,说明它只出现一次。


C语言代码

复制代码
#include <stdlib.h>

int cmp(const void* a, const void* b)
{
    return (*(int*)a - *(int*)b);
}

int singleNumber(int* nums, int numsSize) {
    
    qsort(nums, numsSize, sizeof(int), cmp);
    
    for(int i = 0; i < numsSize - 1; i += 2)
    {
        if(nums[i] != nums[i+1])
            return nums[i];
    }
    
    return nums[numsSize - 1];
}

复杂度分析

复制代码
时间复杂度:O(n log n)
空间复杂度:O(1)

缺点:排序导致时间复杂度不满足题目要求。


五、解法三:位运算(最优解)

核心思想

利用 异或 XOR 运算

异或的三个重要性质:

复制代码
a ^ a = 0
a ^ 0 = a
满足交换律和结合律

例如:

复制代码
2 ^ 2 ^ 1 = (2 ^ 2) ^ 1 = 0 ^ 1 = 1

所有 成对出现的数字都会抵消,最后剩下的就是只出现一次的数字。


算法步骤

  1. 定义变量 res = 0

  2. 遍历数组

  3. 每个元素与 res 做异或

  4. 最终 res 即为答案


C语言代码

复制代码
int singleNumber(int* nums, int numsSize) {
    
    int res = 0;
    
    for(int i = 0; i < numsSize; i++)
    {
        res ^= nums[i];
    }
    
    return res;
}

执行过程示例

输入:

复制代码
[4,1,2,1,2]

计算过程:

复制代码
res = 0

0 ^ 4 = 4
4 ^ 1 = 5
5 ^ 2 = 7
7 ^ 1 = 6
6 ^ 2 = 4

最终结果:

复制代码
4

复杂度分析

复制代码
时间复杂度:O(n)
空间复杂度:O(1)

满足题目要求,是 最优解法


六、总结

解法 时间复杂度 空间复杂度 推荐
哈希表 O(n) O(n)
排序 O(n log n) O(1)
位运算 O(n) O(1) ⭐⭐⭐

最佳方案:位运算(XOR)

原因:

  • 时间复杂度 O(n)

  • 空间复杂度 O(1)

  • 代码简洁


本题属于经典位运算题,也是面试高频题。

相关推荐
lvwangshu6 分钟前
exBSGS 算法
数学·算法
不会就选b7 分钟前
算法日常・每日刷题--<贪心+大根堆>2
数据结构·算法
码艺-Alimjan8 分钟前
维吾尔语数字转文本
java·javascript·python·算法·go
AI服务老曹11 分钟前
算法任务配置完整流程:明厨亮灶项目从0到1怎么做 | AI视频分析算法实践
人工智能·算法·音视频
事圆则缓15 分钟前
Java 常见数据结构与 Android 使用场景
android·java·数据结构
hahaha601621 分钟前
HLS高层次综合设计--axi之burst纠偏
开发语言·算法·fpga开发·c#
hans汉斯26 分钟前
【计算机科学与应用】基于联合熵驱动改进麻雀搜索优化VMD的DAS信号去噪方法
深度学习·算法·yolo·软件工程·汉斯出版社
词却30 分钟前
机器学习入门:手写数字识别与算法对比
人工智能·算法·机器学习
xx~t34 分钟前
嵌入式——Linux软件编程——数据库
linux·c语言·数据库·oracle·sqlite
水饺编程1 小时前
第5章,[Win32 章节] :圆角矩形教学插图绘制程序
c语言·c++·windows·visual studio