260. 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.
For example:
Given nums = [1, 2, 1, 3, 2, 5]
, return [3, 5]
.
算法描述:
由题意知,给出一个数组,在数组中有且只有两个数出现次数为一次,其余数出现过两次,我们要输出一个数组,该数组只包含那两个只出现一次的数。
方法一:对数组进行排序,按照从小到大或从大到小的顺序均可,之后从头至尾遍历排好序的数组,将不相同的数放进定义的容器中,遍历完成后返回容器即可。
方法二:按照这样的思路,将所有的数进行异或操作,(注意:异或操作中可以交换异或顺序)因为相同的数抑或之后为0,所以最后的异或值为那两个不同的数的异或值(一定不为 0),我们定义为 temp,temp 中的“1”表示这两个不同的数在哪一位出现了不同。之后,我们运算 temp = temp & -temp,此时,得到的 temp 为 这两个数出现“1”最小的那一位。(这两个数在这一位上一个为“0”,另一个为“1”)我们将用它来区分。如: 6 = (0110),-6=(1010), 6 & -6 = (0110) & (1010) = 0010 即出现1最低的那一位。之后,对数组进行遍历,temp 与每个数进行“与”操作,如果为 “0”,我们将它分到一组,如果不为 “0”,分到另一组。分组策略为“异或”运算(相同的数异或之后为“0”,“0”与“其它数”“异或”等于“其它数”),最后返回结果。该算法的时间复杂度为O(n),空间复杂度为O(1)。
代码:
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
vector<int> ans={0,0};
int temp=0;
for(int i=0; i<nums.size(); i++){
temp ^= nums[i];
}
temp &= -temp;
for(int i=0; i<nums.size(); i++){
if((nums[i] & temp) != 0){
ans[0] ^= nums[i];
}
else{
ans[1] ^= nums[i];
}
}
return ans;
}
};