左程云异或题总结

异或题总结

1.概念

a、类似于无进位相加

b、0 ^ N = N

c、N ^ N = 0

d、满足交换律和结合律

2.经典性质题目

1⃣️、如何不用额外变量交换两个数

a = a ^ b
b = a ^ b  (a ^ b ^ b == a)
a = a ^ b	 (a ^ b ^ a == b)
# 需要注意a和b可以一样 但是不能指向同一块内存 否则该内存会被刷成0 比如一个数组交换的时候
a = [1, 3, 100]
i = 0
j = 0
(0)a[i] = a[i] ^ a[j]  (a[0] = 0)
(0)a[j] = a[i] ^ a[j]
(0)a[i] = a[i] ^ a[j]

2⃣️、一个数组中有一种数出现奇数次,另一种出现偶数次,怎么找到

# 遍历一遍 不断将取出来的数加入异或 这样偶数次的变成了0 奇数的还是本身
a = [1, 1, 1, 2, 2]

In [19]: eor = 0

In [20]: for i in a:
    ...:     eor ^= i
    ...:

In [21]: eor
Out[21]: 1

3⃣️、将一个int类型的数,提取出最右侧的1来

# a: 01101110010000
#-a: 10010001110000
b = a & (-a)
  = a & (~a + 1)
# b: 00000000010000

In [22]: test = 7
In [23]: ~test + 1
Out[23]: -7

4⃣️、一个数组中有两种数出现奇数次,其他出现偶数次,怎么找到这两种数

# 遍历一遍,不断作异或,最终结果eor = a ^ b, 且a != b,eor必不为0
# a ^ b的结果的某一位若为1则代表a和b在这一位上不一样
# 找到eor的其中一个1的位置,借此区分a和b eor'只异或此位为1的避开另一个数,由此得到其中一个数,另一个数可由eor异或已经得到的数获得
In [24]: a = [1, 1, 2, 2, 3, 5, 5, 5]
In [30]: eor = 0

In [31]: for i in a:
    ...:     eor ^= i

In [32]: flag = eor & (-eor)

In [33]: for i in a:
    ...:     if i & flag != 0:
    ...:         eor_ ^= i

In [34]: print(eor_, eor ^ eor_)
5 3

5⃣️、一个数组中有一种数出现k次,其他数都出现m次,m > 1,k < m,找到出现k次的数, 要求额外空间复杂度O(1),时间复杂度O(n)

# 开一个大小为32的数组 统计每位出现了几次1, 然后遍历每一位,如果%m不为0,则代表这一位上出现k次的数位1,得到最终结果
In [35]: a = [0] * 32

In [36]: arr = [1, 1, 1, 3, 3, 3, 4, 4]
In [39]: for i in arr:
   ...:     for num in range(32):
   ...:         a[num] += (i >> num) & 1
   ...:

In [40]: ans = 0
In [42]: m = 3

In [43]: k = 2

In [44]: for i, x in enumerate(a):
   ...:     if x % m == 0:
   ...:    		 continue
   ...:     if x % m == k:
   ...:         ans |= (1 << i) # ans 不能初始化为-1 否则异或不能给值了
     			 else:
         			 ans = -1
   ...:# 如果数组里有0 需要判断0是不是最终结果 统计0的数量 如果不是 应该返回-1 找不到答案
       if ans == 0:
       	count = 0
         for(x : a):
           if(x == 0):
             count ++
       if count != k:
         ans = -1

In [45]: ans
Out[45]: 4
 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值