每日一题——只出现一次的数字(II)

只出现一次的数字------II

题目链接

注:本题的解法建立在位运算之上,如果对位运算不太了解,建议先看看👉位运算详解


思路

可能有小伙伴做了只出现一次的数字------I后认为这题也可以用异或运算来解决,但是我们需要注意到,本题中数组中的数据,要么出现了三次,要么只出现了一次,我们用异或运算不能做到消除出现了三次的数据而只留下出现了一次的数据,因此需要换一种方法。

这一题,我们可以通过计算二进制位来解决问题。

如果不看只出现了一次的数据,那么由于每个元素都恰出现了三次,那么每个二进制位要么是3个0,要么是3个1,而加上这多出的一个数据,就会使某些二进制位变成4个1,而二进制位仍为3个1的就说明只出现一次的元素的这个二进制位为0。

可以得出结论:

所求数据的第i个二进制位就是数组中所有元素的第i个二进制位之和除以3的余数。

举个例子,对于数组[2,2,2,3]

这样一来,我们就可以通过操作(nums[i] >> i) & 1来求得每个数据的第i个二进制位 ,相加得到total,再total % 3得到只出现一次的数字的第i个二进制位如果这一位为1,最后再利用ret |= 1u << i就可以的到最后的结果

实现代码

c 复制代码
int singleNumber(int* nums, int numsSize){
    int ret = 0;	//设置返回值

    for(int i = 0; i < 32; i++)
    {
        int total = 0;
        
        //计算第i位二进制的和
        for(int j = 0; j < numsSize; j++)
            total += (nums[j] >> i) & 1;
        //如果和取模为1,那么就说明返回值第i位的二进制位也为1
        if(total % 3)
            ret |= 1u << i;
    }
    return ret;
}

可能有小伙伴会疑惑1u是什么意思,为什么要写1u而不是1

1u的意思是将1这个int型数据转换为无符号数,如果我们用1,题目会报错:

1 x 31 位的左移不能用类型"int"表示

而之所以不能表示,是因为:对于32位int类型,需要符号位(最高位)保留一个位置 。在32位int类型中,左移31位时,会将所有的位都移动到符号位,导致整数溢出。溢出后,结果可能不再是期望的值,而是一个负数或者一个非常大的正数。

相关推荐
ACP广源盛1392462567321 分钟前
(ACP广源盛)GSV6172---MIPI/LVDS 信号转换为 Type-C/DisplayPort 1.4/HDMI 2.0 并集成嵌入式 MCU
c语言·开发语言·单片机·嵌入式硬件·音视频
im_AMBER1 小时前
算法笔记 09
c语言·数据结构·c++·笔记·学习·算法·排序算法
是苏浙4 小时前
零基础入门C语言之C语言内存函数
c语言·开发语言
2301_807997386 小时前
代码随想录-day26
数据结构·c++·算法·leetcode
闭着眼睛学算法6 小时前
【双机位A卷】华为OD笔试之【排序】双机位A-银行插队【Py/Java/C++/C/JS/Go六种语言】【欧弟算法】全网注释最详细分类最全的华子OD真题题解
java·c语言·javascript·c++·python·算法·华为od
小欣加油6 小时前
leetcode 3318 计算子数组的x-sum I
c++·算法·leetcode·职场和发展
海琴烟Sunshine8 小时前
leetcode 190. 颠倒二进制位 python
python·算法·leetcode
AI柠檬8 小时前
C语言基于MPI并行计算矩阵的乘法
c语言·c++·算法
海琴烟Sunshine8 小时前
leetcode 338. 比特位计数 python
python·算法·leetcode
czy878747510 小时前
C语言实现观察者模式
c语言·观察者模式