Description:
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?
Solution:
这道题目的基础做法有很多,但是在线性时间,O(1)的空间解决还是有点难度的
首先不难发现,按照我们前面解决问题的方案,全部异或之后的结果是x^y,问题是如何将这两个分开
巧妙的方法是,x^y肯定不为0,那么不妨找到第一个在二进制中为1的bit,表示x和y两个数字,在这个bit上一个是1,一个是0。所以再将所有的nums按照这个bit是0还是1分为两组,各自做异或就能分别求出x和y。
找到第一个为1的bit有很多种方法,简单的一种是
sum & (~(sum - 1))
记得是Steiner Tree里面提到的用法,也可以用循环做。
<span style="font-size:18px;">public class Solution {
public int[] singleNumber(int[] nums) {
int n = nums.length;
int[] ans = new int[2];
int sum = 0;
for (int i = 0; i < n; i++)
sum = sum ^ nums[i];
int highest_bit = sum & (~(sum - 1));
for (int i = 0; i < n; i++) {
if ((nums[i] & highest_bit) == 0)
ans[0] ^= nums[i];
else
ans[1] ^= nums[i];
}
return ans;
}
}</span>