您的位置:首页 > 其它

Single Number II

2016-01-05 10:05 423 查看

题目

Given an array of integers, every element appears three timesexcept for one.
Find that single one.

其他出现3次,找出唯一出现1次的

Note:

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

思路(别人的)

原地址

I'll try to explain ziyihao solution since the first answer is not accurately explained. The main idea of ziyihao's solution is coming from course digital logic. That is, we have a initial state(x, y), and a target state(z), the goal is to find out the binary
operations(z=f(x, y)):

The solution use two bit (a,b) to represent the initial state:
00: appear 3n times
01: appear 3n+1 times
10: appear 3n+2 times

The target state can be easily deducted that we want:

if data incoming: 00 -> 01 ->10 -> 00 if no data incoming, no change.

As a result, we can calculate the table in ziyihao's post:
current   incoming  next
a b            c    a b
0 0            0    0 0
0 1            0    0 1
1 0            0    1 0
0 0            1    0 1
0 1            1    1 0
1 0            1    0 0


The next step is to calculate the binary operations we need from this state table, which is actually a general technique used in digital circuit course. Let's look at bit "a" first:
current   incoming  next
a b            c     a
0 0            0     0
0 1            0     0
1 0            0     1
0 0            1     0
0 1            1     1
1 0            1     0


As mentioned in ziyihao's post, we only need care about the rows has value "1" in "next " column, that is row 3 and row 5.

So we can get:

a=a&~b&~c + ~a&b&c

Use the same technique and we can get the binary operations for b.

代码

int singleNumber(int* nums, int numsSize) {
int a=0;
int b=0;
int c;
int i;
//we need to implement a tree-time counter(base 3) that if a bit appears three time ,it will be zero.
//#curent  income  ouput
//# ab      c/c       ab/ab
//# 00      1/0       01/00
//# 01      1/0       10/01
//# 10      1/0       00/10
// a=~abc+a~b~c;
// b=~a~bc+~ab~c;
for(i=0;i<numsSize;i++)
{
c = nums[i];
int tmp = (~a&b&c)|(a&~b&~c);
b = (~a&~b&c)|(~a&b&~c);
a = tmp;
}
// //we need find the number that is 01,10 => 1, 00 => 0.
return a|b;

}


最重要的是推出那个公式!!!
int tmp = (~a&b&c)|(a&~b&~c);
b = (~a&~b&c)|(~a&b&~c);
a = tmp;
设置tmp变量是因为,计算b的时候需要的a是上一状态,而不是当前状态
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: