剑指56-数组中数字出现的次数 II | 刷题打卡

164 阅读1分钟

写在前面

掘金团队号上线,助你 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的个数 位运算的思路是比较巧妙的:

  1. 用一个数组bits[32]记录在二进制的32位中,每一个数字在这32位中出现1的次数

举个例子:数字7 - 0000 0111,则将bits[0,1,2]都加一

  1. 显而易见,若一个数字出现3次,则这些位数都会加3

承接上例:数字7出现3次,则得到bits数组如右 .... 0000 0333

  1. 因此我们很自然的想到,若对于数组每一位进行 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();
    }
};

原文链接