《剑指Offer》面试题:找出数组中有3个出现一次的数字

这道面试题要求在含有三个出现一次的数字和重复数字的数组中,找出这三个只出现一次的数字。通过分析数字的奇偶性,我们可以逐位扫描并找到一个只出现一次的数字,然后在剩余元素中继续寻找其余两个。该方法巧妙且高效。
摘要由CSDN通过智能技术生成

题目

一个int数组中有三个数字a、b、c只出现一次,其他数字都出现了两次。请找出三个只出现一次的数字。

思路
由于3个数字出现一次,其他数字均出现两次,因此可以得到n一定为奇数。
3个只出现一次的数字,他们的bit位肯定不可能全部相同,也就是说,虽然有些bit位上的数可能相等,但肯定至少存在某一个bit位,这三个数中,有两个数的该bit位为1,一个数的该bit位为0,或者两个数的该bit位为0,一个数的该bit位为1。
我们可以通过扫面int的所有bit位,扫描每个bit位的时候,遍历数组,如果能找出符合上面条件的,我们就可以找出其中的一个只出现一次的数字,该数字与另外两个只出现一次的数的bit位不同。找到一个之后,就可以将其与数组的最后一个元素交换,再在前面n-1个数中找出另外两个就可以了,方法的话,可以直接用上篇博文中介绍的方法,也可以用该博文介绍的思路。

下面要来看下如果找出这个与另外两个数的该bit位不同的数。

先看第一种情况,如果a,b,c三个数中,有两个该bit位为0,另一个为1,我们遍历数组,分别统计该数组元素中该bit位为1和0的元素个数,分别设为count1和count0,并同时将所有该bit位为1的元素异或,所有该bit位为0的元素异或,得到的结果分别设为temp1和temp0。如果count1为奇数,则可能有两种情况,a,b,c三个数的该bit位全为1,或者有两个为0,一个为1,如果有temp0==0,则说明是前一种情况(a,b,c的该bit位全为1的话,所有该bit位为0的每个元素出现了两次,因此异或后的结果为0),即3个只出现一次的数均在第1类中,此时没法找出其中的一个数,则直接跳到下次循环,继续判断下一个bit位,如果temp0不等于0,则说明是后一种情况(说明该比bit位为0的元素异或后没有完全抵消,则说明在此类中有两个数字只出现一次),此时其中一个只出现一次的数字就在另一类中,值就是temp1(重复的元素异或后都抵消了)。

同理:第二种情况也是类似的,如果 count0为奇数时,且temp1!=0时,则说明有两个值出现了一次的数在bit=1的这类中,另一个则在bit=0的那一类中,且值为temp0;

将上面的思路在图上显示如下:

编码实现如下:

/*
一个int数组中有三个数字a、b、c只出现一次,其他数字都出现了两次。请找出三个只出现一次的数字。
*/

/*
思路:按照上面提供的思路,现在3个次数值出现一次的数字中找出其中一个,然后利用上篇博文中找出两个在数组只出现一次的数字的方法。 
*/

#include<stdio.h>
#include<stdlib.h>
int xorArr(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值