您的位置:首页 > 其它

Leetcode算法学习日志-137 Single Number II

2017-11-09 10:21 387 查看

Leetcode 137 Single Number II

题目原文

Given an array of integers, every element appears
three times except for one, which appears exactly once. Find that single one.

Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

题意分析

给定一个数组,数组中有一个元素只出现一次,其余元素出现3次,找出出现一次的那个元素。需要在O(n)时间完成,且不需要额外存储。

解法分析

本题不能有额外存储,也就不能采用散列表来记录,但可以定义一些int变量。这种题型都是采用bit manipulation。从32个比特来看,我们需要对每一个比特构造一个计数器,需要一个32长度的数组来存储,如果某一比特为1的个数为6,表示只出现一次的那个元素在该比特为0,该数组可以表示如下:

1 3 6 11 9 .............................
因为我们只关心模3取余的结果,所以上述计数器又可以表示如下:
1 0 0 2 0................................
可以看到上述计数器只有三个状态,0,1,2,分别表示该比特为1的数字出现次数为3n,3n+1,3n+2,因此上述三种状态可以用两比特来表示,a和b,对于每一比特的三种状态的表示如下:
a b

0 0 3n
01 3n+1
10 3n+2
因此,对于每次加入的数c,可以得到ab的状态转移表:



由此可以写出a和b的表达式,a=a&(~b)&(~c)^(~a)&b&c,b=(~a)&b&(~c)^(~a)&(~b)&c。这是每一比特的状态转移,a和b是32bit数,对于他们的每一位都进行同样的状态转移操作,得到的b就是那个只出现一次的数(b的某一位为1正好表征计数器为3n+1的状态,说明只出现一次的数在该位是1)。C++代码如下:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int a=0,b=0;
int temp;
// int c;
for(int c:nums){//c should be redefined int every iteration
temp=(a&(~b)&(~c))^((~a)&b&c);
b=((~a)&(b)&(~c))^((~a)&(~b)&c);
a=temp;
}
return b;

}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: