【算法】异或 求列表中一种出现奇数次的数据 求列表中两种出现奇数次的数据

求列表中一种出现奇数次的数据

根据异或可以简单的求出

l1 = [11, 22, 33, 22, 11, 11, 11, 22, 22]
a = 0
for i in l1:
    a ^ i
print(a)  # 33

# 异或的功能
"""
0 ^ 任何数据 = 任何数据
相同数据 ^ 相同数据 = 0
1 ^ 0 = 1
2 ^ 0 = 2
1 ^ 1 = 0

多个数同时异或
1 ^ 2 ^ 1
异或也可以互相交换位置,上述就等于
1 ^ 1 ^ 2
0 ^ 2
2
"""
# 所以 上述的代码可以看做
"""
0 ^ 11 ^ 22 ^ 33 ^ 22 ^ 11 ^ 11 ^ 11 ^ 22 ^ 22
0 ^ 11 ^ 11 ^ 11 ^ 11 ^ 22 ^ 22 ^ 22 ^ 22 ^ 33
0 ^ 0 ^ 0 ^ 0 ^ 0 ^ 33
0 ^ 33
33
"""

求列表中两种出现奇数次的数据

异或的使用以及编码层面的操作

l1 = [1, 2, 1, 2, 2, 3, 4, 4, 5, 6, 6, 5]
a, b = 0, 0
for i in l1:
    a ^= i
# 若l1中有两个出现奇数次的数据 那么 a 最终等于 数据1 ^ 数据2
# 两个不同数据的异或 结果 必定不为0 所以二进制层面 至少有一位是1 全为0才是0
# 既 设a: XXX1XXXX 这个1的位置不一定 数量也不一定 所以要通过二进制层面的操作求出最右边的1的位置
# 假若 a: 01010010 那么可以通过取反 + 1的方法 得到 a`:10101110
# 在通过 & 方法 求得 a & a` = 00000010  得到了最右边1的位置
right_one = a & (~a + 1)
# 还记得 异或 的结果吗 这个位置为1 说明 两个奇数在这个位置上 一个为0 一个为1 所以可以将所有数据分为两组
# 一组为 这个位置上是 0  一组为这个位置上为 1
# 再使用 right_one 去与所有数据 & 可以划分出 这个位置为1的数 和这个位置不为1的数
for i in l1:
    if right_one & i == 0:  # 这里也可以写成 right_one & i != right_one
        # 在用 b ^ 这个数 就可以获得该组出现奇数次的数据
        b ^= i
# 最终 b 得到了 该位置上不为1并只出现奇数次的数据
# 通过 a ^ b 就可以得到另一个了
print(b, a ^ b)

# 运行结果
# 2 3

posted on   祁珏  阅读(40)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示