Single Number III (M)
题目
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?
题意
给定一个数组,其中只有两个数只出现了一次,其他所有数都出现了两次。要求找出这两个数。
思路
-
最简单的做法就是使用Set进行操作,将已出现过的从Set中除去,将未出现过的加入到Set中。最后留下的就是要找的两个数。
-
与 0136. Single Number 使用的方法相同,用异或找出这两个数a和b,具体方法如下:
- 对所有数进行异或,得到的结果就是a和b的异或(相同的数异或会抵消得到0),记为xor。
- 因为a和b是不同的数,所以它们二进制的某一位必定不一样,从右到左找到xor中第一个1(相当于从右到左找到a和b二进制第一个不同的位),记为pos。如:3 ^ 5 = 011 ^ 101,pos = 010。
- 将nums中所有的数与pos相与,可以将结果分为两组,区别在于对应二进制位上的数不同,而a和b一定分属于这两个组。
- 接着问题就变成和136一样的情况,将两组数分别异或,得到的就是a和b。
代码实现
Java
Set
class Solution {
public int[] singleNumber(int[] nums) {
Set<Integer> set = new HashSet<>();
for (int num : nums) {
if (set.contains(num)) {
set.remove(num);
} else {
set.add(num);
}
}
int[] ans = new int[set.size()];
int index = 0;
for (int num : set) {
ans[index++] = num;
}
return ans;
}
}
位操作
class Solution {
public int[] singleNumber(int[] nums) {
int[] ans = new int[2];
int xor = 0;
for (int num : nums) {
xor ^= num;
}
int pos = 1;
while ((xor & pos) == 0) {
pos <<= 1;
}
for (int num : nums) {
if ((num & pos) == 0) {
ans[0] ^= num;
} else {
ans[1] ^= num;
}
}
return ans;
}
}
JavaScript
/**
* @param {number[]} nums
* @return {number[]}
*/
var singleNumber = function (nums) {
let xor = 0
for (let num of nums) {
xor ^= num
}
let pos = 1
while (!(pos & xor)) {
pos <<= 1
}
let a = 0
let b = 0
for (let num of nums) {
if (num & pos) {
a ^= num
} else {
b ^= num
}
}
return [a, b]
}
参考
LeetCode 260. Single Number III 题解