[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
相关文章
相关标签/搜索