260.只出现一次的数字III
题目描述
思路:哈希表、异或运算+分治
哈希表
使用哈希表统计数组中每个元素出现的次数。统计完成后,对哈希表进行遍历,找到所有只出现一次的数放入答案中。
Java实现
class Solution {
public int[] singleNumber(int[] nums) {
Map<Integer, Integer> counter = new HashMap<Integer, Integer>();
for (int num : nums) {
counter.put(num, counter.getOrDefault(num, 0) + 1);
}
int[] ans = new int[2];
int index = 0;
for (Map.Entry<Integer, Integer> entry : counter.entrySet()) {
if (entry.getValue() == 1) {
ans[index++] = entry.getKey();
}
}
return ans;
}
}
Python实现
class Solution:
def singleNumber(self, nums: List[int]) -> List[int]:
# 哈希表
counter = Counter(nums)
return [num for num, val in counter.items() if val == 1]
异或运算+分治
异或有如下两条性质:
- 0 a = a 0^a = a 0a=a
-
a
a
=
0
a^a = 0
aa=0
因为除了要求的答案以外的元素均出现两次,可以先对nums中所有元素执行异或操作,得到diff,diff为两答案的异或值(diff必然不为0)。分组重新异或,即可得到答案。
Java实现
class Solution {
public int[] singleNumber(int[] nums) {
// 异或
int diff = 0;
for(int num: nums)
diff ^= num;
diff = diff & (~diff+1);
int ans1 = 0, ans2 = 0;
for(int num: nums){
if((num & diff) > 0)
ans1 ^= num;
else
ans2 ^= num;
}
return new int[]{ans1, ans2};
}
}
Python实现
class Solution:
def singleNumber(self, nums: List[int]) -> List[int]:
# 异或运算
ans = 0
for num in nums:
ans ^= num
ans &= -ans
ans1 = ans2 = 0
for num in nums:
if num & ans:
ans1 ^= num
else:
ans2 ^= num
return [ans1, ans2]