Single Number

题目:http://code.bupt.edu.cn/problem/p/84/

Given an array with N integers where all elements appear three times except for one. Find out the one which appears only once.

 N(1N10^5)  All elements are ranged in [0,2^631] ;

好吧。以前看过每个数都出现两次,只有一个出现一次,找这个数的题目。这个还真新颖。。。

数据卡的O(nlogn)一丁点就不行,甚至O(N*64)都不行。。。无语了。。。在quora上看到有人讲这个题,大开眼界,记录一下。

主要意思就是用xor(a XOR a = 0)

先把代码贴上

        one = two = 0;
        for(i = 0; i < n; ++i) {
            scanf("%lld", &a);
            two |= one&a;
            one ^= a;
            del = ~(one&two);
            one &= del;
            two &= del;
        }
        printf("%lld\n", one);

 

定义:

one:表示只出现过一次的数

two:表示出现过两次的数

del:用来删掉出现三次的数

有如下几种情况:

1、出现一个新的a,通过XOR,放入one中

2、a出现第二次,one中原来有a,one&a就将a放入two中。

3、a出现第三次,要把a从one和two中删掉。

对于下三行代码

            del = ~(one&two);
            one &= del;
            two &= del;

可以看出其目的是将从one和two中二进制中相同位都为1的位置变为0。

 

 

假设现在有4个数(a b a a),走一遍过程。

1# a放到one中,two依然没有数

2# two只有a,one放入b

3# two中依然只有a,one中不再有a(因为被XOR掉了)

4# two中依然有a,one里也存有a,则将one和two二进制中相同位都为1的位置删掉,即删掉a。

 

最后one里剩下的为b,two里面为0;

 ps:one里有a,two里有a指的是a的二进制。

 

 

 

 

 

posted @ 2014-03-28 20:47  AC_Von  阅读(1218)  评论(1编辑  收藏  举报