https://leetcode.com/problems/single-number-iii/
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.Example:
Input:[1,2,1,3,2,5] Output:[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?
一路异或之后可以得到两个目标数纠缠在一起的状态,重点在于分离
一开始设想再以这个纠缠状态为起点一路异或一遍,当某个数使他为零时,就找到了第一个目标数,但是显然这个方法是错的
参考了 https://segmentfault.com/a/1190000004886431
直观上理解就是一种将原数组的划分,分为两个子数组,每个数组中满足“有一个数出现一次,剩下的数出现两次”这一特性,就容易解了
注意取mask的时候类似于树状数组 -n = ~n+1 = ~(n-1)(证明思路:先证带符号数加法与无符号数相同,再证 n+~n+1 = 0,再证~n+1 = ~(n-1),利用10...0后缀)
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
vector<int> result(2);
int combine = 0;
for(int cur : nums){
combine ^= cur;
}
int mask = combine & (~(combine-1));
int a = 0, b = 0;
for(int cur : nums){
if(cur & mask){
a ^= cur;
}else{
b ^= cur;
}
}
result[0] = a;
result[1] = b;
return result;
}