LeetCode-260只出现一次的数字 III
-
题目
给定一个整数数组
nums
,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。 -
思路
-
哈希表
统计数组中每个元素出现的次数,再遍历哈希表,输出次数为1的元素
-
位运算
通过学习只出现一次的数字我们可以得到:
\[A\bigoplus A=0 \]\[A\bigoplus B=B\bigoplus A \]\[A\bigoplus B \bigoplus A=B \]因为当数组中只有一个元素出现一次,其他元素出现两次时,将元素中所有元素异或,即可得到该元素
当数组中有两个元素出现一次(假设为a,b),其他元素为两次,此时将所有元素异或,得到\(a\bigoplus b=sum\),且\(a\bigoplus b \neq 0\),如果为0意味着a,b相等。取sum二进制中的任意一位1,在此位置上,意味着a,b两元素的值不相同,通过\(sum \bigoplus nums[i]==1\)这个条件,就可将数组分为两部分,一部分同在该位置同a相等,一部分同b相等,再将每部分分别求异或和,即可求得这两个元素。
-
-
Code
- 哈希表
class Solution { public: vector<int> singleNumber(vector<int>& nums) { if(nums.size()<=2){ return nums; } map<int,int> m; for(auto i:nums){ m[i]+=1; } vector<int> res; for(auto p:m){ if(p.second==1){ res.push_back(p.first); } } return res; } };
- 位运算
class Solution { public: vector<int> singleNumber(vector<int>& nums) { int sum=0; for(auto i:nums){ sum^=i; } int k=-1; for (int i = 31; i >= 0 && k == -1; i--) { if (((sum >> i) & 1) == 1){ k = i; } } int num1=0,num2=0; for(auto i:nums){ if((i>>k)&1){ num1^=i; } else{ num2^=i; } } return vector<int>({num1,num2}); } };