python学习笔记 day2
位运算
利用位运算实现快速计算
通过^
快速交换两个整数
a = a^b
b = a^b # b = (a^b)^b = a
a = a^b # a = (a^b)^a = b
通过 a & (-a)
快速获取a
的最后为 1 位置的整数。
00 00 01 01 -> 5
&
11 11 10 11 -> -5
---
00 00 00 01 -> 1
00 00 11 10 -> 14
&
11 11 00 10 -> -14
---
00 00 00 10 -> 2
利用位运算实现整数集合
一个数的二进制表示可以看作是一个集合(0 表示不在集合中,1 表示在集合中)。
比如集合 {1, 3, 4, 8}
,可以表示成 01 00 01 10 10
而对应的位运算也就可以看作是对集合进行的操作。
元素与集合的操作:
a | (1<<i) #把 i 插入到集合中
a & ~(1<<i) #把 i 从集合中删除
a & (1<<i) #判断 i 是否属于该集合(零不属于,非零属于)
集合之间的操作:
~a #a补
a & b #a交b
a | b #a并b
a & (~b) #a差b
注意:整数在内存中是以补码的形式存在的,输出自然也是按照补码输出。
【例】Python 的bin()
输出。
print(bin(3)) # 0b11
print(bin(-3)) # -0b11
print(bin(-3 & 0xffffffff))
# 0b11111111111111111111111111111101
print(bin(0xfffffffd))
# 0b11111111111111111111111111111101
print(0xfffffffd) # 4294967293
从结果可以看出:
- Python中
bin
一个负数(十进制表示),输出的是它的原码的二进制表示加上个负号,巨坑。 - Python中的整型是补码形式存储的。
- Python中整型是不限制长度的不会超范围溢出。
所以为了获得负数(十进制表示)的补码,需要手动将其和十六进制数0xffffffff
进行按位与操作,再交给bin()
进行输出,得到的才是负数的补码表示。
练习题
leetcode 习题 136. 只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
尝试使用位运算解决此题。
题目说明:
"""
Input file
example1: [2,2,1]
example2: [4,1,2,1,2]
Output file
result1: 1
result2: 4
"""
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
output = 0
for i in range(len(nums)):
output = output^nums[i]
return output