[优选算法专题五.位运算——常见位运算总结及NO.33~34判定字符是否唯一、丢失的数字]

一、常见位运算总结

1.1基础位运算

|----------|-------------------------|
| 运算符 | 操作 |
| << | 左移 |
| >> | 右移 |
| ~ | 取反 |
| & | 对应二进制位有0就是0 |
| | | 对应二进制位有1就是1 |
| ^ | 对应二进制位,相同为0相异为1 / 不进位相加 |

对于^运算的不进位相加解释:假设为

0 1 0

0 1 1

那么不进位相加就是 0 0 1,这个理解在我们后面是有用的

1.2给一个数n,确定他的二进制位中的第x为是0还是1

利用&(对应二进制位有0就是0)运算即可,将 n >> x后,他的第x为就在最右边,那么此时& 一个1,那么就只会得到1 或 0,如果是1,那么这个位上是1,反之则是0

(n>> x) &1

1.3将一个数n的二进制表示的第x位修改为1

方法: n | (1 << x) 即可:

这样,能保证其他位的不变,将对应x位改为1

1.4将一个数n的二进制表示的第x位修改为0

要想将某一位修改为0,那么就让这一位 & 0即可,但是怎么得到仅是这一位为0的数字呢??

方法: 我们将1 << x后取反即可

这样,通过**n & (~(1 << x))**就能得到所求

1.5位图的思想

哈希表实际上大多数情况下是个数组,通过数组的内容来存储数据

实际上二进制位同样有这个效果:

通过二进制位上是0还是1来存储信息,而我们上面的1.2 ~ 1.4的方法主要是为了以后操作位图做好准备

1.6提取一个数n二进制表示中最右侧的1

方法:n & -n

-n操作实际上就是将原数取反后 +1 的操作,

这样我们会发现,n与-n相比,原数最右侧的1的左边变成原来相反,右侧则不变,还是0

那么我们将 n & -n后,就能提取出最右侧的1

1.7去掉一个数n二进制表示中最右侧的1

方法: n & (n-1)

  • 实际上n-1的操作就是从右往左进行借位的操作,因为在遇到最右侧的1之前,其余位都是0,是不够-1的,那么就要借位,直到遇见1
  • 那么n-1后就得到与原来的n相比:最右侧的1(包括这个1)的右侧都是原来的相反数,而左侧的不变
  • 那么我们将n & n-1后,就能将原数最右侧的1去掉
1.8异或运算的运算律

实际上我们用前面讲到的不进位相加就能理解

(1)a ^ 0 = a

(2)a ^ a = 0(形象称为消消乐)

(3)a ^ b ^ c = a ^ (b ^ c)

那么不进位相加实际上就是每一列抵消1的过程,既然这样,那就和顺序毫无关系了,因此满足交换律


题目链接:

面试题 01.01. 判定字符是否唯一

题目描述:

题目解析:

核心逻辑解析:

  1. 长度优化判断 :由于小写字母只有 26 个,若字符串长度超过 26,必然存在重复字符,直接返回false,避免后续无效计算。

  2. 位图(bitmap)原理 :利用整数的二进制位作为 "标记位",每一位对应一个小写字母(第 0 位对应'a',第 1 位对应'b',...,第 25 位对应'z')。

    • 例如:bitmap = 0b101(二进制)表示'a'(第 0 位)和'c'(第 2 位)已出现过。
  3. 位运算操作

    • 检查字符是否出现(bitmap >> i) & 1bitmap右移i位,使第i位移动到最低位,再与1按位与,若结果为1,说明该字符已出现。
    • 标记字符出现bitmap |= 1 << i1左移i位得到一个只有第i位为1的数,再与bitmap按位或,将第i位设为1,完成标记。

复杂度分析:

  • 时间复杂度 :O (n),其中n为字符串长度,仅需遍历一次字符串。
  • 空间复杂度 :O (1),仅使用一个整数bitmap,空间消耗与输入规模无关。

题目链接:

268. 丢失的数字

题目描述:

题目解析:

核心原理说明:

  1. 异或运算的特性

    • 任何数字与自身异或结果为 0(如 a ^ a = 0
    • 任何数字与 0 异或结果为该数字本身(如 a ^ 0 = a
    • 异或运算满足交换律和结合律(如 a ^ b ^ c = a ^ c ^ b
  2. 算法逻辑

    • 假设数组长度为 n,则完整的数字序列应该是 0, 1, 2, ..., n(共 n+1 个数字)
    • 数组 nums 是完整序列中缺少一个数字后的结果(共 n 个数字)
    • 当我们把数组中的所有元素与 0~n 的所有数字进行异或时:
      • 完整序列中存在的数字会出现两次(一次在数组中,一次在 0~n 中),异或后抵消为 0
      • 缺失的数字只在 0~n 中出现一次,最终会保留在结果中
  3. 时间复杂度O(n),只需遍历数组一次和 0~n 一次

  4. 空间复杂度O(1),只使用了常数个额外变量

相关推荐
June`3 小时前
前缀和算法:高效解决区间和问题
算法·1024程序员节
wwlsm_zql4 小时前
「赤兔」Chitu 框架深度解读(十四):核心算子优化
人工智能·1024程序员节
pearlthriving4 小时前
list的介绍
数据结构·list·1024程序员节
Zz_waiting.5 小时前
服务注册 / 服务发现 - Nacos
nacos·服务发现·1024程序员节
fruge6 小时前
Less:让CSS开发更简单的预处理器
1024程序员节
月临水6 小时前
Git 学习笔记
笔记·git·学习·1024程序员节
MeowKnight9586 小时前
【C】占位符知识点总结
1024程序员节
春日见6 小时前
“package.xml”和“CMakeLists.txt”配置
1024程序员节