LeetCode 137. Single Number II 解题报告
题目描述
Given an array of integers, every element appears three times except for one. Find that single one.
示例
Example 1:
input: [1]
output: 1
Example 2:
input: [2, 2, 3, 2]
output: 3
限制条件
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
解题思路
我的思路:
首先说明一下这道题的题意,我理解的题意是数组中仅有一个元素出现一次,而其他元素出现了三次。我在官网上测试过了[1, 1, 1, 2, 2]这种仅有一个元素出现不是三次的用例,发现没有结果返回,所以我觉得题意就是说仅有一个元素出现了一次,而不是Discuss里有人认为的仅有一个元素出现次数不足三次。
这道题我没有想出来,最后通过的解法没有符合O(n)的时间复杂度,而是O(nlogn)。
思路就是先排序,然后从头开始遍历,如果某个元素与左右两个都不相同就是单独元素,特殊情况是头尾的情况,分别单独处理即可,因为用到了排序,所以时间复杂度是O(nlogn)
参考思路:
看了Discuss里大神的解法,真是惊叹到无以复加的地步。这里给出一个我理解的解法。
充分利用数组元素是int类型这一特点,统计所有元素的第
i
个bit上为1的个数,因为题目说了其它元素出现了3次,而特殊元素只出现了1次,所以当统计的个数不能整除3就表明特殊元素在第
代码
我的代码
class Solution {
public:
int singleNumber(vector<int>& nums) {
if (nums.size() == 1)
return nums[0];
sort(nums.begin(), nums.end());
size_t i = 0;
for (; i < nums.size(); i++) {
if ((i == 0 && nums[i] != nums[i + 1]) ||
(i == nums.size() - 1 && nums[i] != nums[i - 1]) ||
(nums[i] != nums[i - 1] && nums[i] != nums[i + 1]))
break;
}
return nums[i];
}
};
参考代码
class Solution {
public:
int singleNumber(vector<int>& nums) {
int sum = 0;
int ans = 0;
for (int i = 0; i < 32; i++) {
sum = 0;
for (int n: nums) {
if ((n >> i) & 1)
sum++;
}
if (sum % 3)
ans |= 1 << i;
}
return ans;
}
};
总结
这道题我是真的想不出来,真不知道大神们是怎么想的,好佩服。他们的解法适用于数组中仅一个元素出现一次,而其他元素出现n次的情况,条件设为sum % n就行。除了这种解法,Discuss还有其他的解法,不过我没怎么理解就没在这里贴出来了。光是上面贴出来的解法也让我大开了眼界O(∩ _ ∩)O哈哈~。
终于腾出了时间填好这个坑,明天继续,希望能够自己做出来,加油加油~