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)

  • 代码简洁


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

相关推荐
Darkwanderor1 天前
什么数据量适合用什么算法
c++·算法
zc.ovo1 天前
河北师范大学2026校赛题解(A,E,I)
c++·算法
py有趣1 天前
力扣热门100题之环形链表
算法·leetcode·链表
py有趣1 天前
力扣热门100题之回文链表
算法·leetcode·链表
Kk.08021 天前
数据结构|链表 刷题
数据结构·链表
leo_messi941 天前
多线程(五) -- 并发工具(二) -- J.U.C并发包(八) -- CompletableFuture组合式异步编程
android·java·c语言
jie188945758661 天前
c语言------
c语言·开发语言
月落归舟1 天前
帮你从算法的角度来认识二叉树---(二)
算法·二叉树
清华都得不到的好学生1 天前
数据结构->1.稀疏数组,2.数组队列(没有取模),3.环形队列
java·开发语言·数据结构