Given an array of integers, every element appears twice except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
题目分析:这道题解出来不难,但是有没有能在O(n)时间和O(1)空间里解决的方法呢?我首先想到的是用HashSet,每次把元素放进去,当元素已经被包含,就remove,最后set里剩下的就是那个single的元素,但是这样的解决方案是时间O(n), 空间O(n)的,还是需要额外空间。用指针的话可以做到空间O(1),但是时间就O(n^2)了。最后看discussion才知道可以用bit manipulation的骚操作,有时候bit manipulation在某些数字操作上可以达到意想不到的效果,比如这里,我们发现5^5 = 0,每个数字和自身异或就是0,所以把数组里全部数字异或一遍以后就可以得到single number了,很取巧但是又很精妙。
代码一:hashset: 时间O(n),空间O(n)
public int singleNumber(int[] nums) {
if (nums == null || nums.length == 0) return -1;
HashSet<Integer> set = new HashSet<>();
int result = 0;
for (int i : nums) {
if (set.contains(i)) {
set.remove(i);
} else {
set.add(i);
}
}
for (int i : set) {
result = i;
}
return result;
}
代码二:bit manipulation: 时间O(n),空间O(1)
public int singleNumber(int[] nums) {
if (nums == null || nums.length == 0) return -1;
int result = 0;
for (int i : nums) {
result = result ^ i;
}
return result;
}