首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
01 | 合格程序员的第一步:算法与数据结构
02 | 如何事半功倍地学习算法与数据结构
03 | 如何计算算法的复杂度
04 | 如何通过LeetCode来进行算法题目练习
05 | 理论讲解:数组&链表
06 | 面试题:反转一个单链表&判断链表是否有环
07 | 理论讲解:堆栈&队列
08 | 面试题:判断括号字符串是否有效
09 | 面试题:用队列实现栈&用栈实现队列
10 | 理论讲解:优先队列
11 | 面试题:返回数据流中的第K大元素
12 | 面试题:返回滑动窗口中的最大值
13 | 理论讲解:哈希表
14 | 面试题:有效的字母异位词
15 | 面试题:两数之和
16 | 面试题:三数之和
17 | 理论讲解:树&二叉树&二叉搜索树
18 | 面试题:验证二叉搜索树
19 | 面试题:二叉树&二叉搜索树的最近公共祖先
20 | 理论讲解:二叉树遍历
21 | 理论讲解:递归&分治
22 | 面试题:Pow(x,n)
23 | 面试题:求众数
24 | 理论讲解:贪心算法
25 | 面试题:买卖股票的最佳时机
26 | 理论讲解:广度优先搜索
27 | 理论讲解:深度优先搜索
28 | 面试题:二叉树层次遍历
29 | 面试题:二叉树的最大和最小深度
30 | 面试题:生成有效括号组合
31 | 理论讲解:剪枝
32 | 面试题:N皇后问题
33 | 面试题:数独问题
34 | 理论讲解:二分查找
35 | 面试题:实现一个求解平方根的函数
36 | 理论讲解:字典树
37 | 面试题:实现一个字典树
38 | 面试题:二维网格中的单词搜索问题
39 | 理论讲解:位运算
40 | 面试题:统计位1的个数
41 | 面试题:2的幂次方问题&比特位计数问题
42 | 面试题:N皇后问题的另一种解法
43 | 理论理解:动态规划(上)
44 | 理论理解:动态规划(下)
45 | 面试题:爬楼梯
46 | 面试题:三角形的最小路径和
47 | 面试题:乘积最大子序列
48 | 面试题:股票买卖系列
49 | 面试题:最长上升子序列
50 | 面试题:零钱兑换
51 | 面试题:编辑距离
52 | 理论讲解:并查集
53 | 面试题:岛屿的个数&朋友圈(上)
54 | 面试题:岛屿的个数&朋友圈(下)
55 | 理论讲解: LRU Cache
56 | 面试题:设计和实现一个LRU Cache缓存机制
57 | 理论讲解:布隆过滤器
当前位置:
首页>>
技术小册>>
算法面试通关 50 讲
小册名称:算法面试通关 50 讲
### 39 | 理论讲解:位运算 在编程与算法的世界中,位运算(Bitwise Operations)是一种直接对整数在内存中的二进制表示形式进行操作的技术。它不仅在底层系统编程、图形处理、加密算法等领域有着广泛应用,也是许多高效算法设计的基石,特别是在面试中,位运算题目往往能考察求职者的逻辑思维能力和对计算机底层原理的理解。本章节将深入解析位运算的基本概念、常用操作及其在实际问题中的应用。 #### 一、位运算基础 ##### 1.1 二进制表示 在计算机中,所有的数据(包括整数、浮点数、字符等)最终都以二进制(Base 2)的形式存储在内存中。二进制数由0和1两个数字组成,每一位代表一个二进制位(bit),是计算机中最小的信息单位。例如,十进制数9在二进制中表示为`1001`。 ##### 1.2 字节与位 字节(Byte)是计算机存储数据的基本单位,通常由8个二进制位组成。因此,一个字节可以表示的最大十进制数是`2^8 - 1 = 255`(从00000000到11111111)。 ##### 1.3 位运算的重要性 位运算之所以重要,是因为它们允许程序员直接操作数据的二进制表示,从而实现高效的数据处理和算法优化。与常规的算术运算(如加、减、乘、除)相比,位运算通常更快,因为它们直接在硬件层面执行,减少了CPU的指令周期。 #### 二、位运算的基本操作 位运算主要包括以下几种基本操作: ##### 2.1 位与(AND) 位与操作使用符号`&`表示。对两个数的二进制表示进行位与操作,只有当两个相应的位都为1时,结果位才为1,否则为0。例如,`5 & 3`(二进制为`101 & 011`)的结果为`1`(二进制`001`)。 **应用**:常用于检查某个位是否被设置(如权限检查)、清零特定位等。 ##### 2.2 位或(OR) 位或操作使用符号`|`表示。对两个数的二进制表示进行位或操作,只要两个相应的位中有一个为1,结果位就为1。例如,`5 | 3`(二进制为`101 | 011`)的结果为`7`(二进制`111`)。 **应用**:常用于设置特定的位(如打开某个选项)、合并两个数的位信息等。 ##### 2.3 位异或(XOR) 位异或操作使用符号`^`表示。对两个数的二进制表示进行位异或操作,当两个相应的位不同时,结果位为1;相同时,结果位为0。例如,`5 ^ 3`(二进制为`101 ^ 011`)的结果为`6`(二进制`110`)。 **应用**:常用于切换位的状态(如开关操作)、实现无进位加法等。 ##### 2.4 位非(NOT) 位非操作是单目运算,使用符号`~`表示。它对数的二进制表示进行取反操作,即0变为1,1变为0。注意,位非操作的结果取决于数的表示方式(如补码表示法)和位数(如32位或64位整数)。 **应用**:较少直接用于算法设计,但在某些特定场景下(如快速取反)有其用武之地。 ##### 2.5 位移操作 位移操作包括左移(`<<`)和右移(`>>`,在某些语言中还有无符号右移`>>>`)。左移操作将数的二进制表示向左移动指定的位数,右边超出的位被丢弃,左边新增的位用0填充。右移操作则相反,将数的二进制表示向右移动指定的位数,对于算术右移,左边新增的位用符号位填充(即正数用0填充,负数用1填充),而无符号右移则总是用0填充。 **应用**:常用于快速乘以或除以2的幂次方、实现位级的数据处理(如位图操作)等。 #### 三、位运算的应用实例 ##### 3.1 交换两个数的值 不使用临时变量,仅通过位运算交换两个数的值是一个经典的面试题。一种常见的解法是利用异或操作的性质: ```c a = a ^ b; b = a ^ b; // 此时b = (a ^ b) ^ b = a a = a ^ b; // 此时a = (a ^ b) ^ a = b ``` ##### 3.2 判断一个数是否为2的幂 一个数如果是2的幂,那么它的二进制表示中只有一个1,其余位都是0。利用这个性质,我们可以通过位与操作来判断: ```c bool isPowerOfTwo(int n) { return n > 0 && (n & (n - 1)) == 0; } ``` 解释:如果`n`是2的幂,那么`n-1`的二进制表示中所有比`n`的最低位高的位都会变成1(例如,`4(100)`的下一个数是`3(011)`),这样`n & (n - 1)`的结果就会是0。 ##### 3.3 反转一个数的二进制表示 反转一个数的二进制表示,即将其每一位0变为1,1变为0,可以通过位非操作与位移操作结合实现: ```c unsigned int reverseBits(unsigned int n) { n = (n >> 16) | (n << 16); n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8); n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4); n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2); n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1); return n; } ``` 这段代码通过多次分组和位移操作,逐步将每一位反转。 #### 四、总结 位运算作为计算机编程中的一项基础而强大的工具,其重要性不言而喻。掌握位运算不仅能够提升编程效率,还能在解决特定问题时提供独特的视角和思路。本章节从位运算的基本概念出发,详细介绍了位与、位或、位异或、位非以及位移操作等基本操作,并通过实例展示了位运算在算法设计中的应用。希望读者能够通过本章节的学习,深入理解位运算的精髓,并在实际编程中灵活运用。
上一篇:
38 | 面试题:二维网格中的单词搜索问题
下一篇:
40 | 面试题:统计位1的个数
该分类下的相关小册推荐:
编程之道-算法面试(上)
数据结构与算法(中)
编程之道-算法面试(下)
数据结构与算法之美
数据结构与算法(下)
业务开发实用算法精讲
数据结构与算法(上)