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:
- The order of the result is not important. So in the above example,
[5, 3]
is also correct.
- 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