LeetCode 136. 只出现一次的数字(C语言)

该博客介绍了LeetCode第136题的解决方案,通过位运算来高效地找出数组中只出现一次的数字。文章分析了位运算在算法中的应用,特别是异或操作如何将重复的数字变为0,从而保留唯一出现的数字。此外,还提供了解决此类问题的C语言代码实现。

136. 只出现一次的数字

Description


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

说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:
输入: [2,2,1]
输出: 1

示例 2:
输入: [4,1,2,1,2]
输出: 4

Analyze


给定的函数如下:

  • @param nums 一个整数数组
  • @param numsSize 数组长度
  • @return 只出现一次的数字

这题乍一看可以暴力解,即把每一个数都跟其他的数对比,如果有相同的就下一个,如果没有就直接返回这个数,实际上也确实可以,但是因为要把每一个数都跟其他的数对比,时间复杂度就比较高了,有一种比较快的方法是用位运算来解决。
题中数字都出现了两次,只有一个出现了一次,而在位操作中有一个 “异或” 操作可以把相同的数给去掉,具体如下:

“异或”,在C语言中用 ^ (shift + 6)表示,异或是位运算的一种,表示把两个数字 “按位异或”,即把两个数转换为二进制,然后分别对每一位做异或操作,相同为0,不同为1,比如12 ^ 5

3210
1100
0101
1001

最后结果为1001,转换为10进制就是9,这是异或的基本运算。既然异或是相同为0,不同为1,那么显然可以得出几个性质:

  • 任何数跟自己异或都等于 0
  • 任何数跟 0 异或都等于原来的数
    并且异或满足交换律,即12 ^ 5 ^ 1212 ^ 12 ^ 5 的答案是一样的,因为他们都是转换成二进制来计算的,因此某一位是 0 ^ 1 ^ 0 或者 0 ^ 0 ^ 1都是一样的,这三个数不会改变。
    回到题目,显然如果把数组中的所有数都进行一次异或操作,那些出现了两次的数字都会变成0,而目标数字在最后会被保留。

Realization


  • 特殊情况处理


如果只有一个数字那么直接返回

  • 循环

  • 返回

  • 提交

Dictionary


位运算对于程序效率的提高是很有帮助的,因为数字在计算机中本就是以二进制方式保存的,因此使用位运算可以明显的提高效率。对于这个题,其实这个解法不仅仅是针对这个题,与之类似的其他题都是这样解,比如题目改成所有数字出现偶数次,只有一个数字出现奇数次,那么这题的解法甚至是代码都是一样的。因此灵活使用位运算对解题还有实际开发都很有帮助。

附源代码


int singleNumber(int* nums, int numsSize){
    if(numsSize == 1)return nums[0];
    int result = nums[0];
    for(int i = 1; i < numsSize; ++i)
    {
        result = result^nums[i];
    }
    return result;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值