算法日常・每日刷题--<位运算>4

137. 只出现一次的数字 II - 力扣(LeetCode)137. 只出现一次的数字 II - 给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。 示例 1:输入:nums = 2,2,3,2输出:3示例 2:输入:nums = 0,1,0,1,0,1,99输出:99 提示: * 1 <= nums.length <= 3 * 104 * -231 <= numsi <= 231 - 1 * nums 中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次https://leetcode.cn/problems/single-number-ii/description/

一、题意先看懂

数组里:

  • 只有一个数字出现 1 次
  • 剩下所有数字都恰好出现 3 次 要求:O (n) 时间、O (1) 额外空间,找出那个唯一的数。

二、核心思路:按二进制每一位单独统计

把所有数字拆成 32 位二进制,对每一位分别统计 1 出现的总次数

  1. 重复 3 次的数字:该位如果是 1,会贡献 3 个 1;
  2. 唯一 1 次的数字:该位如果是 1,会额外多 1 个 1;

将每一位上的0和1的数据进行统计

会出现下面四种,将其%3的结果和我们所要求的该只出现一次的数据是一致得

逐位统计

遍历全部数字,统计当前 bit 上有多少个 1;

计数 %3,余数为 1 则给结果的这一位置 1。

cpp 复制代码
class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ret=0;
        for(int i=0;i<32;i++)
        {
            //统计1出现的个数
            int total=0;
            for(auto e:nums)
            {
                total+=(e>>i)&1;
            }
            //确定该32位位置的值是0还是1
            if(total%3)
            {
                total=total%3;
                ret=ret|(total<<i);
            }
        }
        return ret;
    }
};