LeetCode 137. Single Number II 解题报告

来源:互联网 发布:阿里云报价 编辑:程序博客网 时间:2024/06/05 21:01

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就表明特殊元素在第i个bit上是1,所以我们把结果的第i个bit设为1,通过检查32个bit,这样我们就构造出了特殊元素,最后返回结果即可,时间复杂度是O(32n)。


代码

我的代码

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哈哈~。
终于腾出了时间填好这个坑,明天继续,希望能够自己做出来,加油加油~

0 0
原创粉丝点击