位运算
1,只出现一次的数字(136)
采用位运算中的异或运算,异或运算满足交换律与结合律 ^
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
res = 0
for i in nums:
res ^= i
return res
2,颠倒二进制位(190)
采用位运算中的右移>>与左移<<操作
class Solution:
# @param n, an integer
# @return an integer
def reverseBits(self, n):
res = 0
count = 32
while count:
res<<=1
res+=n&1
n>>=1
count-=1
return int(bin(res),2)
3,位1的个数(191)
采用位运算中的&操作 num&(num-1)可以消去num末尾的0
class Solution(object):
def hammingWeight(self, n):
"""
:type n: int
:rtype: int
"""
res = 0
while n:
n = n&(n-1)
res += 1
return res
4,判断一个数字是否是2的幂(231)
采用位元算中的&操作,也是num&(num-1),因为如果一个数字是2的幂次,那么num-1相对于num而言,除了最高位不是1,其余各位均是1,则num&(num-1)结果为0
class Solution(object):
def isPowerOfTwo(self, n):
"""
:type n: int
:rtype: bool
"""
return n>0 and n&(n-1)==0
5,1~n中缺失的数据(268)
利用位运算中的异或操作^ ,将index,value两个数字都进行异或操作,最后的数字将是最终的结果
class Solution(object):
def missingNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
missing = len(nums)
for i, num in enumerate(nums):
missing ^= i ^ num
return missing
6,判断一个数字是否为4的幂(342)
利用位运算中的&操作,以及考虑4的幂的二进制位表示的规律,4 的幂次方的数的二进制表示 1 的位置都是在奇数位,让所给数字与101010101010101010101010101010
&操作,其中上述二进制的数字的数字长度最长为32位,0x55555555=101010101010101010101010101010
class Solution(object):
def isPowerOfFour(self, num):
"""
:type num: int
:rtype: bool
"""
if num <= 0:
return False
#先判断是否是 2 的幂
elif num &(num-1) != 0:
return False
#如果与运算之后是本身则是 4 的幂
elif num & 0x55555555 !=num:
return False
return True
7,两整数之和,不用加减号(371)
在位运算操作中,异或的一个重要特性是无进位加法,a ^ b 得到了一个无进位加法结果,如果要得到 a + b 的最终值,我们还要找到进位的数,把这二者相加
在 Python 中,整数不是 32 位的,也就是说你一直循环左移并不会存在溢出的现象,这就需要我们手动对 Python 中的整数进行处理,手动模拟 32 位 INT 整型。
具体做法是将整数对 0x100000000 取模,保证该数从 32 位开始到最高位都是 0。
class Solution(object):
def getSum(self, a, b):
"""
:type a: int
:type b: int
:rtype: int
"""
# 2^32
MASK = 0x100000000
# 整型最大值
MAX_INT = 0x7FFFFFFF
MIN_INT = MAX_INT + 1
while b != 0:
# 计算进位
carry = (a & b) << 1
# 取余范围限制在 [0, 2^32-1] 范围内
a = (a ^ b) % MASK
b = carry % MASK
return a if a <= MAX_INT else ~((a % MIN_INT) ^ MAX_INT)
8,找不同(389)
将字符首先转成ASCII码,然后将两个字符串所有的ASCII码进行位运算中的异或操作,最后得到的结果再进行反转ASCII码操作
class Solution(object):
def findTheDifference(self, s, t):
"""
:type s: str
:type t: str
:rtype: str
"""
temp = s+t
res = 0
for i in range(len(temp)):
res ^= ord(temp[i])
return chr(res)
9,数字转换成为16进制数(405)
class Solution:
def toHex(self, num: int) -> str:
num &= 0xFFFFFFFF
s = "0123456789abcdef"
res = ""
mask = 0b1111
while num > 0:
res += s[num & mask]
num >>= 4
return res[::-1] if res else "0"
10,计算汉明距离(461)
首先将两个数字进行位运算的异或操作,然后再转到问题3上面去
class Solution(object):
def hammingDistance(self, x, y):
"""
:type x: int
:type y: int
:rtype: int
"""
temp = x^y
count = 0
while temp:
count+=1
temp = temp &(temp-1)
return count
11,计算一个数字的补码(476)
先得到一个和所给数字位数相同的全是1的二进制数,然后将这一个二进制数与所给的数进行异或操作,就可以得到该数字的补码
class Solution(object):
def findComplement(self, num):
"""
:type num: int
:rtype: int
"""
length = len(bin(num))-2 #二进制位数的长度
n = (1 << length) - 1 #将1左移length位,并减1得到二进制数位全是1的长度位length的数
return n ^ num #异或
12,判断一个数是否位交替位二进制数(693)
首先将所给数字右移一位,与原来的数字进行异或操作看和是否为一
class Solution(object):
def hasAlternatingBits(self, n):
"""
:type n: int
:rtype: bool
"""
tmp = n^(n>>1)
return tmp&(tmp+1) == 0