问题1:
题目描述
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
示例 1:
输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]
思路:
先对所有数字进行一遍异或,得到的结果是两个数字的异或,
假定为x,二进制表示为010,即表明两个数字二进制第二位数不相同,通过这种方式将数组分为两部分,分别做异或,可以得到结果
C++ 代码
#include<vector>
using namespace std;
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int val = 0;
for(auto num:nums)
val = val^num;
int div = 1;
while((val&div)==0){
div<<=1;
}
int a=0,b=0;
for(auto num:nums){
if(num&div){
a^=num;
}else{
b^=num;
}
}
return vector<int>({a,b});
}
};
问题2:
题目描述
在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。
示例 1:
输入:nums = [3,4,3,3]
输出:4
思路:
对于出现三次的数字,将其转为二进制表示,其每一位一定都出现三次,因此统计二进制每一位的出现次数,取余后可以得到正确结果
#include<vector>
using namespace std;
class Solution {
public:
int singleNumber(vector<int>& nums) {
vector<int>cnt(32);
for(auto tmp:nums){
unsigned int num = tmp;//注意是无符号右移 这样能够获得每一个对应位
for(int i = 0;i<32;i++){
if(num&1)cnt[i]++;
num >>=1;
}
}
int res = 0;
for(int i =0;i<32;i++){
res<<=1;
res|=cnt[31-i]%3;
}
return res;
}
};