题目
Given an array of integers, every element appears three times except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
原题地址
解题思路
数组中含有n个数,其中一个数只出现1次,其余个数均出现3次,就只出现1次的数。
首先应该想到的就是 计数法,先对数组排序,然后统计每个数出现的次数,找出出现次数为1个数;
更高级一点的方法还是用 位运算,充分发掘数字二进制中的0和1出现的规律。一个数字是由0和1组成的,如果这个数字出现3次,那么这个数字中各个位上0和1出现的次数也应该是3次。按照这样统计数组中所有数的各个位1的个数,如果个数是1个倍数,这所求数字该位不为1。
举例如下:
数组: 1, 3, 1, 5, 1, 6, 5, 6, 6, 5
对应的二进制位 001, 011, 001, 101, 001, 110, 101, 110, 110, 101
从右往左看:
第1位 1 的个数为 7,则所求结果数字中的第1位也应该为1;
第2位 1 的个数为 4,则所求结果数字中的第2位也应该为1;
第3位 1 的个数为 6,则所求结果数字中的第3位为0。
根据上面的分析所得结果为 011,即为3。
首先应该想到的就是 计数法,先对数组排序,然后统计每个数出现的次数,找出出现次数为1个数;
更高级一点的方法还是用 位运算,充分发掘数字二进制中的0和1出现的规律。一个数字是由0和1组成的,如果这个数字出现3次,那么这个数字中各个位上0和1出现的次数也应该是3次。按照这样统计数组中所有数的各个位1的个数,如果个数是1个倍数,这所求数字该位不为1。
举例如下:
数组: 1, 3, 1, 5, 1, 6, 5, 6, 6, 5
对应的二进制位 001, 011, 001, 101, 001, 110, 101, 110, 110, 101
从右往左看:
第1位 1 的个数为 7,则所求结果数字中的第1位也应该为1;
第2位 1 的个数为 4,则所求结果数字中的第2位也应该为1;
第3位 1 的个数为 6,则所求结果数字中的第3位为0。
根据上面的分析所得结果为 011,即为3。
代码实现
代码一:排序计数
class Solution {
public:
int singleNumber(int A[], int n) {
if(A==NULL || n<=0) return 0;
sort(A, A+n);
int count = 1;
int ret = A[0];
for(int i=1; i<n; ++i){
if(A[i] == A[i-1])
++count;
else{
if(count == 1){
break;
}
else if(count == 3){
count = 1;
}
}
ret = A[i];
}
return ret;
}
};
代码二:位运算
class Solution {
public:
int singleNumber(int A[], int n) {
if(A==NULL || n<=0) return 0;
int count = 0;
int ret = 0;
for(int i=0; i<32; ++i){
count = 0;
int d = 1<<i;
for(int j=0; j<n; ++j){
if( A[j] & d )
++count;
}
if(count % 3 != 0)
ret = ret | d;
}
return ret;
}
};
如果你觉得本篇对你有收获,请帮顶。
另外,我开通了微信公众号--分享技术之美,我会不定期的分享一些我学习的东西.
另外,我开通了微信公众号--分享技术之美,我会不定期的分享一些我学习的东西.
你可以搜索公众号:
swalge
或者扫描下方二维码关注我
(转载文章请注明出处: http://blog.csdn.net/swagle/article/details/28394529 )