剑指 Offer II 004. 只出现一次的数字 ](https://leetcode-cn.com/problems/WGki4K/)
难度中等40
给你一个整数数组 nums
,除某个元素仅出现 一次 外,其余每个元素都恰出现 **三次 。**请你找出并返回那个只出现了一次的元素。
示例 1:
输入:nums = [2,2,3,2]
输出:3
示例 2:
输入:nums = [0,1,0,1,0,1,100]
输出:100
提示:
1 <= nums.length <= 3 * 104
-231 <= nums[i] <= 231 - 1
nums
中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次
**进阶:**你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
解法 1:
class Solution {
public:
int singleNumber(vector<int>& nums) {
sort(nums.begin(), nums.end());
int n(0);
for(int i(0); i < nums.size(); i++)
{
if(i > 0 && i < nums.size() - 1)
{
if(nums[i - 1] != nums[i] && nums[i + 1] != nums[i])
{
n = nums[i];
break;
}
}
else if(i == 0)
{
if(nums.size() > 1 && nums[i + 1] != nums[i])
{
n = nums[i];
break;
}
else if(nums.size() == 1)
{
n = nums[i];
break;
}
}
else if(i == nums.size() - 1)
{
if(nums[i - 1] != nums[i])
{
n = nums[i];
break;
}
}
}
return n;
}
};
解法 2:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int res(0);
for(int i(0); i < 32; i++)
{
int sum(0);
for(int j(0); j < nums.size(); j++)
{
sum += (nums[j] >> i) & 1;
}
if(sum % 3)
{
res |= (1 << i);
}
}
return res;
}
};
心得:
最开始看到这道题,我有两个想法:第一是利用哈希表进行统计,第二是进行排序后统计。这两个方法都各有利弊,第一种方法会导致空间复杂度为 O ( n ) O(n) O(n),第二种方法会导致时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)。在看了题解以后,我才意识到可以利用位运算统计每一位的和,从而计算答案的每一位。