LeetCode 面试经典 150 题 | 位运算
目录
- 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 ai⊗ai=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 a1⊗a2⊗...⊗a7⊗...⊗an=0⊗a7⊗0=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 是否相同。
相关文章:

LeetCode 面试经典 150 题 | 位运算
目录 1 什么是位运算?2 67. 二进制求和3 136. 只出现一次的数字4 137. 只出现一次的数字 II5 201. 数字范围按位与 1 什么是位运算? ✒️ 源自:位运算 - 菜鸟教程 在现代计算机中,所有数据都以二进制形式存储,…...
postMessage 收到消息类型 “webpackWarnings“
场景描述: 当A系统中的parent页面使用iframe内嵌C系统的child页面,并且在parent页面中通过postMessageg给child页面发送消息时,如果C系统中使用了webpack,则webpack也会给child页面发送消息 ,消息类型为webpackWarnings。那么如何…...

计算机基础(day1)
1.什么是内存泄漏?什么是内存溢出?二者有什么区别? 2.了解的操作系统有哪些? Windows,Unix,Linux,Mac 3. 什么是局域网,广域网? 4.10M 兆宽带是什么意思?理论…...
cesium添加流动线
1:新建Spriteline1MaterialProperty.js文件 import * as Cesium from cesium;export function Spriteline1MaterialProperty(duration, image) {this._definitionChanged new Cesium.Event();this.duration duration;this.image image;this._time performance.…...
使用java自带的队列进行存取数据ArrayBlockingQueue 多线程读取ExecutorService
场景: 防止接收数据时处理不过来导致阻塞,使用ArrayBlockingQueue队列存储数据后,以多线程的方式处理数据 保证系统性能。 package com.yl.demo.main4;import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurr…...

【音视频之SDL2】Windows配置SDL2项目模板
文章目录 前言 SDL2 简介核心功能 Windows配置SDL2项目模板下载SDL2编译好的文件VS配置SDL2 测试代码效果展示 总结 前言 在开发跨平台的音视频应用程序时,SDL2(Simple DirectMedia Layer 2)是一个备受欢迎的选择。SDL2 是一个开源库&#x…...
JavaScript 里的深拷贝和浅拷贝
JavaScript 里的深拷贝和浅拷贝 JS中数据类型分为基本数据类型和引用数据类型。 基本类型值指的是那些保存在栈内存中的简单数据段。包含Number,String,Boolean,Null,Undefined ,Symbol。 引用类型值指的是那些保存…...

Oracle基础-集合
集合:两个结果集的字段个数和字段类型必须相同,才能使用集合操作。 --UNION 并集 重复行会去重 (SELECT A,B FROM DUAL UNION SELECT C,D FROM DUAL) UNION (SELECT A,B FROM DUAL UNION SELECT E,F FROM DUAL ); --UNION ALL 全集 包含所有记录 不去重…...

《浅谈如何培养树立正确的人工智能伦理观念》
目录 摘要: 一、引言 二、《机械公敌》的情节与主题概述 三、人工智能伦理与法律问题分析 1.伦理挑战 2.法律问题 四、培养正确的人工智能伦理观念的重要性 五、培养正确的人工智能伦理观念的途径与方法 1.加强教育与宣传 2.制定明确的伦理准则和规范 3.…...

uniapp实现局域网(内网)中APP自动检测版本,弹窗提醒升级
uniapp实现局域网(内网)中APP自动检测版本,弹窗提醒升级 在开发MES系统的过程中,涉及到了平板端APP的开发,既然是移动端的应用,那么肯定需要APP版本的自动更新功能。 查阅相关资料后,在uniapp的…...
【Golang 面试 - 进阶题】每日 3 题(六)
✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/UWz06 📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏…...

Unity横板动作游戏 -项目准备
项目准备 这是一篇 Unity 2022 最新稳定版本的教程同步笔记,本文将会讲解一些开始学习必须的条件。 安装环境 首先是安装 UnityHub,然后在 UnityHub 中安装 Unity 的版本(2022)。 只需要安装 开发者工具 和文档即可,导出到其他平台的工具等…...
基于Gunicorn + Flask + Docker的高并发部署策略
标题:基于Gunicorn Flask Docker的高并发部署策略 引言 随着互联网用户数量的增长,网站和应用程序需要能够处理越来越多的并发请求。Gunicorn 是一个 Python WSGI HTTP 服务器,Flask 是一个轻量级的 Web 应用框架,Docker 是一…...

jdk版本管理利器-sdkman
1.什么是sdkman? sdkman是一个轻量级、支持多平台的开源开发工具管理器,可以通过它安装任意主流发行版本(例如OpenJDK、Kona、GraalVM等等)的任意版本的JDK。通过下面的命令可以轻易安装sdkman: 2.安装 curl -s "https://…...

Kafka知识总结(事务+数据存储+请求模型+常见场景)
文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 事务 事务Producer保证消息写入分区的原子性,即这批消…...

C#中重写tospring方法
在C#中,重写ToString方法允许你自定义对象的字符串表示形式。当你想要打印对象或者在调试时查看对象的状态时,重写ToString方法非常有用。 默认情况下,ToString方法返回对象的类型名称。通过重写这个方法,你可以返回一个更有意义…...

【机器学习基础】机器学习的数学基础
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈Python机器学习 ⌋ ⌋ ⌋ 机器学习是一门人工智能的分支学科,通过算法和模型让计算机从数据中学习,进行模型训练和优化,做出预测、分类和决策支持。Python成为机器学习的首选语言,…...
fastapi之零
FastAPI 详细介绍 FastAPI 是一个现代、快速(高性能)的 web 框架,用于构建 API。它基于标准的 Python 类型提示,使用 Starlette 作为 web 框架,Pydantic 进行数据验证和解析。以下是对 FastAPI 的详细介绍,…...

SpringBoot整合PowerJob 实现远程任务
PowerJob介绍 PowerJob 是全新一代分布式任务调度和计算框架,提供了可视化界面,可通过单机、远程等形式调用任务并提供了运行监控和日志查看的功能模块,是当前比较流行的分布式定时任务框架之一; PowerJob 官网文档地址 环境搭建…...

【扒模块】DFF
图 医学图像分割任务 代码 import torch import torch.nn as nnfrom timm.models.layers import DropPath # 论文:D-Net:具有动态特征融合的动态大核,用于体积医学图像分割(3D图像任务) # https://arxiv.org/abs/2403…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...