題目描述:
Given an array of integers, every element appears twice except for one. Find that single one.數組
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?app
要完成的函數:
int singleNumber(vector<int>& nums)函數
說明:
一、給定一組數,這組數中除了有一個元素只出現一次,其餘元素都出現了兩次,要求輸出這個只出現一次的元素的值。spa
二、時間複雜度O(n),也就是隻能從頭至尾遍歷一次;空間複雜度O(1),只能使用常數級的空間。code
三、照這道題目的要求來看,既不能常規作法的定義一個數組,記錄每一個數出現了幾回;也不能雙重循環找到出現兩次的數,而後把它們都刪掉,接着繼續遍歷,直到最後只剩下出現一次的數。因此這道題目要求只能遍歷一遍,那就只能從數學上尋找方法了。blog
四、這道題目筆者本人想了很長時間,都不知道採用什麼數學方法好,直到在discuss中看到大神采用異或(XOR)的作法……如下舉例說明爲何異或可以處理這道問題。ip
舉例說明:
先說明一點,全部整數在計算機中都採用二進制的表示方法。如下舉兩個例子:element
一、數組爲一、一、2,在計算機中表示爲0001,0001,0010,那麼0001^0001=0000,接着0000^0010=0010。最後獲得的結果是2,也就是隻出現一次的這個數,2。數學
二、數組爲一、二、1,在計算機中表示爲0001,0010,0001,那麼0001^0010=0011,接着0011^0001=0010。最後獲得的結果是2,也就是隻出現一次的這個數,2.it
爲何會這樣子?
由於異或是兩個相同的數則異或結果爲0,兩個不一樣的數異或結果爲1,而且異或知足交換律和結合律,因此咱們能夠獲得這樣的結論:A^B^C^B^D^C^A=D。
異或實際上是「記錄」了全部出現過的數,只要你第二遍出現,異或結果就會爲0,直到一個只出現一次的數,那麼異或結果最終爲這個只出現一次的數的數值。
這個結論其實我思考了一會,才明白了過來。異或可以記錄曾經出現過的數,而後一直在等待第二遍出現,來異或爲0。若是一直沒有第二遍出現,數組中全都是隻出現一遍的數,那麼最終結果會是很奇怪的。各位同窗不妨試試。
異或就是我想要的那個數學方法。
代碼:
int singleNumber(vector<int>& nums)
{
for(int i=1;i<nums.size();i++) nums[0]^=nums[i]; return nums[0]; }