刷题笔记2:用位运算找“只出现一次的一个数”

2024-06-13 05:52

本文主要是介绍刷题笔记2:用位运算找“只出现一次的一个数”,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. & 和 | 的基本操作

137. 只出现一次的数字 II - 力扣(LeetCode)

先对位运算的操作进行复习:

1、>> 右移操作符

移位规则:⾸先右移运算分两种:
1. 逻辑右移:左边⽤0填充,右边丢弃
2. 算术右移:左边⽤原该值的符号位填充,右边丢弃
一般的编译器都默认使用算术右移。

2. << 左移操作符

移位规则:左边抛弃、右边补0  

 注意,所有的操作符只能移动整数。

3. & 和 |

& //按位与
| //按位或
&:两位数都为1时为1,其余时候为0
|  :  两位数只要有一个为1,就为1,其余时候为0
并且,| ^ &的优先级都是低于==和!=的, 需要判断语句时记得加括号
意义

& :

  • 清零特定位 (m中特定位置0,其它位为1,s=s&m或s&=m)
  • 取某数中指定位 (m中特定位置1,其它位为0,s=s&m或s&=m)  比如 最经典的
    for(i=0;i<32;++i) //int是32位二进制整数
    int ans =(x>>i)& 1;

           由于1的补码是 000...0001,x每次右移1位来将每一位分别和0000....0001进行按位与,因此每一轮循环都能将x的一位赋值给ans,让ans依次得到x的每一个二进制位。

| :

多用于将左操作数某些位置1,其它位不变 (m特定位置为1,其余位置为0,希望将s的特定位置改为1,s |= m)

经典:根据特定的条件将ans中的某几位调整为1(将0000..0001中的1一位一位的往前挪)

if(.....)
ans |= (1 << i);


有了以上铺垫,我们再学习思路:

  由于除了答案,其余每个数字出现三次,所以这三个相同数字为一组中,就有三个一模一样的32为二进制数据(3个1或3个0),我们将第n位上的所有数据加在一起再对3取模,得到的数据就是ans在这一个二进制位上该有的数据。(很多个3和0取出来的模都为0,此时不论ans对应的这一位是1或0,都能被正确赋值) 

答案:

int singleNumber(vector<int>& nums) {int ans = 0;for (int i = 0; i < 32; ++i) {int x = 0;for (int j = 0; j < nums.size(); ++j) {x += (nums[j] >> i) & 1;}if (x % 3) {ans |= (1 << i);}}return ans;}

 2.小试牛刀

136. 只出现一次的数字 - 力扣(LeetCode)

 

依然是找出只出现一次的数据,不过按位异或就可以了

^  : 双目运算符按位异或,相异位1,相同为0

 int singleNumber(vector<int>& nums) {int ans=0;for(auto e:nums){ans^=e;}return ans;}

3.位运算 x & -x 来获取x的lowbit(取出二进制下X最低位的1)

        假设x为正数(位操作符都只对整数有用),在x变成-x时,除了第一位的符号位变化外,在由原码变到反码再到补码(取反加一)时,取反加一中的 “加一”,一定会加到反码由低到高的第一个0上,而反码所有的0都对应的是原码(正数)的1,(所以反码的第一个0对应的就是原码的第一个1)当反码的第一个0(假定这个0在p位置)被加成1后,就可以通过&运算或得  “最低位在p位置并且是1”的数据。

       我们可以认为x &-x是一种取得最低位1的技巧,并且这个用法对负数也凑效。

并且,在y = x & -x后,y是个除了符号位和p位置以外,其余位置都是0的数。

来个大的:

260. 只出现一次的数字 III - 力扣(LeetCode)

                    

     就像刚刚的小试牛刀,我们可以用异或消掉除了ans数组(用于存放两个只出现一次的数a, b)之外的所有数据。不过这两个被异或在一起的数据(x = a^b)该怎么分开呢?

分开的方法:

    对于x,x的每一个1,一定都是由一个数的1和另一个数的0组成的。

在这个理论的基础上,我们通过x & -x来获得一个和x的最低位1(假设在位置p)相同,其他(除最高位)都是0的数字y。我们通过 判断位置p是否为1将nums数组分成两组,所以ans数组中的两个数字一定就被分开了,两组中剩下的其他数字一定是成对出现的,将两个组分别全部异或就能得到答案。

没有全部通过,原因是当测试用例中有x为-2^31时,-x(2^31)没法被放进int

 我们处理如下:

会在x处出现-2^31次方的,答案一定是0和-2^31,否则x不会等于-2^31

并且在下文中,0和-2^31也的确会分开,因此达到目的。

各位都是工科生,仔细想想按位异或的最后一步就明白了。

这篇关于刷题笔记2:用位运算找“只出现一次的一个数”的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1056451

相关文章

C/C++中OpenCV 矩阵运算的实现

《C/C++中OpenCV矩阵运算的实现》本文主要介绍了C/C++中OpenCV矩阵运算的实现,包括基本算术运算(标量与矩阵)、矩阵乘法、转置、逆矩阵、行列式、迹、范数等操作,感兴趣的可以了解一下... 目录矩阵的创建与初始化创建矩阵访问矩阵元素基本的算术运算 ➕➖✖️➗矩阵与标量运算矩阵与矩阵运算 (逐元

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

Python判断for循环最后一次的6种方法

《Python判断for循环最后一次的6种方法》在Python中,通常我们不会直接判断for循环是否正在执行最后一次迭代,因为Python的for循环是基于可迭代对象的,它不知道也不关心迭代的内部状态... 目录1.使用enuhttp://www.chinasem.cnmerate()和len()来判断for

电脑多久清理一次灰尘合? 合理清理电脑上灰尘的科普文

《电脑多久清理一次灰尘合?合理清理电脑上灰尘的科普文》聊起电脑清理灰尘这个话题,我可有不少话要说,你知道吗,电脑就像个勤劳的工人,每天不停地为我们服务,但时间一长,它也会“出汗”——也就是积累灰尘,... 灰尘的堆积几乎是所有电脑用户面临的问题。无论你的房间有多干净,或者你的电脑是否安装了灰尘过滤器,灰尘都

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

uva 575 Skew Binary(位运算)

求第一个以(2^(k+1)-1)为进制的数。 数据不大,可以直接搞。 代码: #include <stdio.h>#include <string.h>const int maxn = 100 + 5;int main(){char num[maxn];while (scanf("%s", num) == 1){if (num[0] == '0')break;int len =

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识