参考链接
http://www.cnblogs.com/changchengxiao/p/3413294.html
题目描述
Single Number II
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?
题目分析
题目大意:
给出一个数组,除了一个数字,剩下的数字都出现了三次。
思路一:
我们可以对每一个数字的每一个位进行统计再mod3.
如:先统计所有数据中bit0位是1的个数。最后mod3,就得出出现一次的数字的bit0是否为1,因为其他数字如果出现就会出现3次。最后mod3就是0
如:5,5,1,5
0101010100010101
每一个bit相加 mod3---------
0001
int singleNumber(int A[], int n) {
int i = 0, j = 0, ret = 0,count = 0;
for(i = 0; i< 32;i++)//32位整数
{
for(j = 0;j<n;j++)
{
if((A[j]>>i) & 1)count++; //易错点:不要把&写成&&
}
ret |= (count%3)<<i;
count = 0; //这里需要清0
}
return ret;
}
这样32位数字需要进行32次循环。
这样复杂度就是O(32n)=O(n)
思路二:
int singleNumber(int A[], int n) {
int one=0, two=0, three=0; //one记录出现一次,two记录出现两次,three记录出现三次
int i = 0;
for (i=0;i<n;i++)
{
two |= one & A[i]; //出现两次的是上一次出现一次,与本次的数字与。然后再或上原来就是两次的。
one ^= A[i]; //记录只出现一次的。因为出现两次的就异或为0了,然后记录在两次里了
three = one & two; //三次就是两次和一次的且
one &= ~three; //清除出现三次的
two &= ~three;
//printf("%d--%d---%d\n",one,two,three);
}
return one;
声明三个变量,one,two,three,one记录只出现一次的bit,two记录只出现2次的bit,three记录出现三次的位。
two |= one & A[i];出现两次的等于之前出现一次的与本次即将出现的位取交集。再与原来就是两次的取并集。
类似思路救出三个数字。
代码示例
#include
using namespace std;
#if 0
/*
统计每一个bit的个数,再mod3
*/
class Solution {
public:
int singleNumber(int A[], int n) {
int i = 0, j = 0, ret = 0,count = 0;
for(i = 0; i< 32;i++)//32位整数
{
for(j = 0;j
>i) & 1)count++; //易错点:不要把&写成&&
}
ret |= (count%3)<
推荐学习C++的资料
C++标准函数库
在线C++API查询
map使用方法