[Leetcode] Single Number III, Solution

Given an array of numbers  nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.
For example:
Given  nums = [1, 2, 1, 3, 2, 5], return  [3, 5].
Note:
  1. The order of the result is not important. So in the above example, [5, 3] is also correct.
  2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?
[Thought]
關於single number的解法,由於只有一個未知數,比較直觀: http://fisherlei.blogspot.com/2013/11/leetcode-single-number-solution.html。

這題有兩個未知數,直接作異或確定是不行的,那麼如何經過一些變換把這道題分解開,使得能夠應用Single Number的解法來作,纔是這個題目有意思的地方。
首先,對於數組A, 假設存在b,c兩個數字,在數組中只出現了一次,那麼對於整個數組進行異或操做的話,
^[A]   =  b^c ,  由於其餘的數由於出現了兩次,異或的過程當中就被清零了。

可是僅僅經過最後異或出來的值,是沒辦法求出b和c的值的, 可是足以幫咱們把b和c劃分到不一樣的子數組中去。

一個整數有32位bit,對於b和c,除非二者是相同的數,不然必定存在第K位bit,二者是不一樣的。 看下面的例子,
當找到這個K之後,就能夠按照第K位bit是否等於1,將A數組劃分紅兩個子數組,而這兩個子數組分別包含了b和c,那麼剩下的就只須要把single number的算法直接應用到這兩個子數組上,就能夠獲得b和c了。

[Code]
1:  class Solution {  
2: public:
3: vector<int> singleNumber(vector<int>& nums) {
4: int length = nums.size();
5: // get the xor result of the array, b ^ c
6: int xor_result = 0;
7: for(int i =0; i< length; i++) {
8: xor_result ^= nums[i];
9: }
10: // get the K of first bit, which equals 1
11: int first_one_index = 0;
12: for(first_one_index =0; first_one_index< 32; first_one_index++) {
13: if((xor_result>>first_one_index) & 1 == 1) {
14: break;
15: }
16: }
17: // use k to split the array into two part
18: // xor the sub array, if the element's Kth bit also equals 1, b
19: int xor_twice = 0;
20: for(int i =0; i< length; i++) {
21: if((nums[i]>>first_one_index) & 1 == 1) {
22: xor_twice ^= nums[i];
23: }
24: }
25: // with b, easy to get c by math
26: vector<int> result = {xor_twice, xor_result ^ xor_twice };
27: return result;
28: }
29: };

Git hub: https://github.com/codingtmd/leetcode/blob/master/src/Single_Number_III.cpp
相關文章
相關標籤/搜索