巧用异或

异或规律#

异或有以下规律

  1. 0^N = N
  2. N^N = 0
  3. 交换律 a ^ b = b ^ a
  4. 结合律 a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c
  5. 自反性 a ^ b ^ a = b

使用异或交换数据#

一般的交换方式, 利用临时变量:

a = 1
b = 2
temp = a
a = b
b = temp

但你也可以使用异或的方法交换:

a = 1
b = 2
a = a ^ b # 1 ^ 2
b = a ^ b # 1 ^ 2 ^ 2 = 1
a = a ^ b # 1 ^ 2 ^ 1 = 2

三次异或操作, 交换两个变量的值

注意: 异或交换变量时, 不能为引用类型, 否则为被清空

解决一些算法题#

出现奇数次的 1 个数字#

问题位置: 剑指 Offer II 070. 排序数组中只出现一次的数字
问题描述:
给定一个只包含整数的有序数组 nums ,每个元素都会出现两次,唯有一个数只会出现一次,请找出这个唯一的数字。

示例 1:
输入: nums = [1,1,2,3,3,4,4,8,8]
输出: 2

示例 2:

输入: nums = [3,3,7,7,10,11,11]
输出: 10

题解#

非常简单, 由于异或的自反性(a ^ b ^ a = b), 所以只要将全部数异或, 那么得到的肯定是只出现一次的那个数

代码#

class Solution:
def singleNonDuplicate(self, nums: List[int]) -> int:
eor = 0
for i in nums:
eor = eor ^ i
return eor

出现奇数次的 2 个数字#

题目位置: 剑指 Offer 56 - I. 数组中数字出现的次数
问题描述:
一个整型数组nums里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。
要求时间复杂度是 O(n),空间复杂度是 O(1)。

示例 1:
输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]

示例 2:
输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]

题解#

假设不同的两个数为ab
由于有两个数, 我们无法通过一次异或得到, 但是我们可以通过一次异或得到a ^ b
由于ab不可能相等, 那么, a ^ b != 0, 即 a ^ b的二进制位一定至少会有一个 "1"

# 如
arr = [1, 1, 2, 2, 3, 4]
# 全部异或得到 3 ^ 4 != 0
# 二进制位:
011
100
-------
111

根据这一点, 我们可以把数据分为两半: 某一位有"1"和某一位无"1", ab就分别在这两半中
接下来, 只需要对这两半数据全部异或即可得到两个数ab

思路已经清晰了, 现在的重点要确定 "某一位" 时第几位, 我们需要提取出来, 不然没将数对半分
如何做呢? 记住 一个数最后位的 1 等于 一个数 与上 自己取反+1 即可, 下面是解释:

eor = 101011100
right_one = eor & (~eor + 1)
"""
eor = 101011100
~eor = 010100011
~eor+1 = 0101000100
& 0000000100
"""

代码#

class Solution:
def singleNumbers(self, nums: List[int]) -> List[int]:
eor = 0
# 同样先全部异或
for i in nums:
eor = eor ^ i
# 确定eor最右边的1
right_one = eor & (~eor + 1)
eor2 = 0
for i in nums:
# 将数据分为两半, &right_one = 0 或 != 0
if right_one & i == 0:
# 继续异或, 得到第一个数
eor2 = eor2 ^ i
# eor ^ eor2 得到第二个数
eor = eor ^ eor2
return eor, eor2
posted @   403·Forbidden  阅读(304)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示
主题色彩