写在前面
掘金团队号上线,助你 Offer 临门! 点击 查看详情
题目描述
在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。
示例 1:
输入:nums = [3,4,3,3]
输出:4
示例 2:
输入:nums = [9,1,7,9,7,9,7]
输出:1
限制:
1 <= nums.length <= 10000
1 <= nums[i] < 2^31
解题思路:位运算
bits数组含义:bits[32]
,长度为32,表示数字在二进制表示下第i位为1的个数
位运算的思路是比较巧妙的:
- 用一个数组
bits[32]
记录在二进制的32位中,每一个数字在这32位中出现1的次数
举个例子:数字7 - 0000 0111,则将bits[0,1,2]都加一
- 显而易见,若一个数字出现3次,则这些位数都会加3
承接上例:数字7出现3次,则得到bits数组如右 .... 0000 0333
- 因此我们很自然的想到,若对于数组每一位进行 mod 3 运算,就可以抵消这些出现3次数字的变动
承接上例:bits数组变为 .... 0000 0000
代码:位运算
class Solution {
public:
int singleNumber(vector<int>& nums) {
vector<int> bits(32,0);
for(auto num : nums) {
for(int i=0;i<32;i++) {
bits[i] += num & 1;
num >>= 1;
}
}
int res = 0;
for(int i=31; i>=0; i--) {
res <<= 1;
res += bits[i] % 3;
}
return res;
}
};
解题思路:哈希表
哈希表的思路是显而易见的,就不过多叙述了
代码:哈希表
class Solution {
public:
int singleNumber(vector<int>& nums) {
unordered_set<int> once, twice;
for(auto &num : nums) {
if(once.count(num)) {
twice.insert(num);
once.erase(num);
}
else if(twice.count(num))
continue;
else
once.insert(num);
}
return *once.begin();
}
};