問題1:問題是一堆數,只有一個數只出現1次,其餘數都出現2次,怎麼求出這個數?spa
咱們知道位運算裏面的異或操做,當兩個數相同時,獲得的結果是零。因此咱們簡單的把全部數一塊兒求異或就獲得了答案。code
更通常的,只有1個數出現奇數次,其餘數都出現偶數次,均可以這麼解決。blog
代碼以下io
class Solution { public: int singleNumber(vector<int>& nums) { int ones = 0, i; for (i = 0; i < nums.size(); ++i) ones ^= nums[i]; return ones; } }
問題2:問題是一堆數,只有2個數只出現1次,其餘數都出現2次,怎麼求出這個數?class
基於上面的題,咱們知道了,只有1個數的狀況下怎麼求出這個數。若是對於本題,咱們用上面的方法,求出的結果是這兩個只出現1次的數的異或。方法
咱們知道若是這兩個數異或結果中某一位是1,說明這2個數在這一位是不一樣的。所以咱們能夠取出這一位,而後用這一位給數分桶,兩桶中的數就分別變成了問題1。di
代碼以下co
class Solution { public: vector<int> singleNumber(vector<int>& nums) { int ones = 0, left = 0, right = 0, i; for (i = 0; i < nums.size(); ++i) ones ^= nums[i]; ones &= -ones;//取出最低不爲0的一位 for (i = 0; i < nums.size(); ++i) { if (ones & nums[i]) left ^= nums[i]; else right ^= nums[i]; } return {left, right}; } };
問題2:問題是一堆數,只有3個數只出現1次,其餘數都出現2次,怎麼求出這個數?位運算
基於上面的題,咱們又知道了,只有2個數的狀況下怎麼求出這2個數。若是對於本題,咱們只須要稍微改動上面的方法,就獲得了答案。return
用上面的方法,分桶求出後,咱們獲得兩個數,其中一個是這三個數的某個數自己,另外一個是其餘兩個數的異或。
若是對兩個桶再分桶一次,那麼包含一個數的那個桶,獲得了那個數自己和0, 另一個桶分桶就獲得了剩下的兩個數。
代碼以下
class Solution { public: vector<int> singleNumber(vector<int>& nums) { int ones = 0, left = 0, right = 0, a = 0, b = 0, c = 0, d= 0, i; for (i = 0; i < nums.size(); ++i) ones ^= nums[i]; ones &= -ones;//取出最低不爲0的一位 for (i = 0; i < nums.size(); ++i) { if (ones & nums[i]) left ^= nums[i]; else right ^= nums[i]; } left &= -left; right &= -right; for (i = 0; i < nums.size(); ++i) { if (ones & nums[i]) if (left & nums[i]) a ^= nums[i]; else b ^= nums[i]; else if (right & nums[i]) c ^= nums[i]; else d ^= nums[i]; } if (a == 0) return {b, c, d}; if (b == 0) return {a, c, d}; if (c == 0) return {a, b, d}; return {a, b, c}; } };