每日OJ题_位运算⑥_力扣137. 只出现一次的数字 II

目录

力扣137. 只出现一次的数字 II

解析代码


力扣137. 只出现一次的数字 II

137. 只出现一次的数字 II

难度 中等

给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。

你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。

示例 1:

输入:nums = [2,2,3,2]
输出:3

示例 2:

输入:nums = [0,1,0,1,0,1,99]
输出:99

提示:

  • 1 <= nums.length <= 3 * 10^4
  • -2^31 <= nums[i] <= 2^31 - 1
  • nums 中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次

class Solution {
public:
    int singleNumber(vector& nums) {

    }
};

解析代码

1. 基础位运算:

&:按位与,有0就是0

| :按位或,有1就是1

^ :按位异或,相同为0,相异为1/无进位相加

        之前用暴力和sort写过了,现在再用位运算写一下,思路就是把全部数的二进制位加起来,模3(一个数出现一次,其它出现n次就是模n),因为如果不看只出现一次的数,其它二进制位加起来不是3n个0就是3n个1,那一位全加起来模3的话剩的就是只出现一次的数的二进制位。

class Solution {
public:
    int singleNumber(vector& nums) {
        int ret = 0;
        for(int i = 0; i < 32; ++i) // 依次修改ret的32个比特位->0改1
        {
            int sum = 0;
            for(auto e : nums)
            {
                // if(((e >> i) & 1) == 1)
                // {
                //     ++sum; // 依次统计所有数的第i位二进制位
                // }
                sum += ((e >> i) & 1); // 即上面注释掉的代码简化,不是加0就是加1
            }
            if(sum %= 3) // 说明这是只出现一次的数剩的1
            {
                ret |= (1 << i); // ret第i位改为1
            }
        }
        return ret;
    }
};

你可能感兴趣的:(每日OJ题,leetcode,算法,c++,位图,位运算)