題目:http://code.bupt.edu.cn/problem/p/84/app
Given an array with N integers where all elements appear three times except for one. Find out the one which appears only once.atom
N(1≤N≤10^5) All elements are ranged in [0,2^63−1] ;spa
好吧。之前看過每一個數都出現兩次,只有一個出現一次,找這個數的題目。這個還真新穎。。。code
數據卡的O(nlogn)一丁點就不行,甚至O(N*64)都不行。。。無語了。。。在quora上看到有人講這個題,大開眼界,記錄一下。blog
主要意思就是用xor(a XOR a = 0)three
先把代碼貼上element
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);
定義:get
one:表示只出現過一次的數it
two:表示出現過兩次的數class
del:用來刪掉出現三次的數
有以下幾種狀況:
一、出現一個新的a,經過XOR,放入one中
二、a出現第二次,one中原來有a,one&a就將a放入two中。
三、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的二進制。