程序中的所有数在计算机内存中都是以二进制的形式存储;由于位运算直接对内存数据进行操作,不需要转成十进制,因此处理速度非常快
| 符号 | 描述 | 规则 |
|---|---|---|
| & | 与 | |
| | | 或 | |
| 异或 | 二进制位上相同为0,不同为1 | |
| << | 左移 | 各二进制位全部左移若干位,高位丢弃,低位补0 |
| >> | 右移 | 无符号数:高位补0;有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移) |
-#### 136. 只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
解题思路
1.可以想要使用字典
2.使用位运算: x ^ x = 0, 相同的元素异或后消消乐 0 ^ x = x
代码实现
def singleNumber( nums):
res = 0
for num in nums:
res ^= num
return res
or
def singleNumber(nums):
return reduce(lambda x, y: x ^ y, nums)
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为[汉明重量])。
示例1:
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。
解题思路
1.清零最低位1的方法: x & (x - 1)
2.当每次遍历的值不为0时,进入清零的逻辑中
代码实现
def hammingWeight(n):
ret = 0
# 非零的情况(表示还有为1的二进制位)
while n:
n &= n - 1 # 低位清零
ret += 1
return ret
给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。
如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。
示例 1:
输入: n = 1
输出: true
解释: 20 = 1
解题思路
如果整数是2的幂次方:
1.该数 > 0
1.表示该数只有一个二进制位为1。
代码实现
def isPowerOfTwo(n):
return n > 0 and (n & (n - 1)) == 0
给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。
示例 1:
输入: n = 2
输出: [0,1,1]
解释:
0 --> 0
1 --> 1
2 --> 10
解题思路
通常而言,可以在每到一个数时就独立的计算某个元素1的个数;
但是正常来说:每个元素和之前元素是存在 + 1的关系的,是不是代表二进制位1的个数有什么关联呢?
当在由小范围推导整体,元素间存在重叠关系时,就该想到动态递归思路:
dp[x] = dp[x & (x - 1)] + 1
当前元素1的个数 = 上一个元素(该元素低位清零对应的值) + 1(当前清零的1位)
实现代码
def countBits(n):
res = [0] * (n + 1)
for i in range(1, n + 1):
res[i] = res[i & (i - 1)] + 1
return res
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
示例 1:
输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
解题思路
转换成以位运算的方式思考:(N = 4)
1.每一行只能放置1个棋子,那么存在四种放置方式 1000\0100\0010\0001
2.当上一回放置1个棋子后,本行的限制条件包括 cols、diagonals1、diagonals2
比如:当确认了第一行、第二行后,第三行的限制条件怎么确认呢?
当拿到所有的限制条件后,如何得到所有的可选位?
拿到的可选位,类似如:1010000,那么如何一位位的获取呢?
通过遍历,不断的拿到最低位的零:
while bits:
# 拿到最后一位 1
p = bits & (-bits)
doSomething()....
# 清除之前拿到过的最后一位非0位
bits &= (bits - 1)
代码实现
部分实现代码
def solveNQueens(n):
count = 0
def dfs(row = 0, col = 0, pie = 0, na = 0):
# 结束条件
if row >= n:
nonlocal count
count += 1
return
# 小心小于零的情况(1出现的位置超出了 N 的限制)
bits =(~(col|pie|na)) & ((1<<n) - 1)
# 当还有空位时
while bits:
# 拿到最低位的1
p = bits & (-bits)
dfs(row + 1, col|p, (pie | p) << 1, (na|p)>>1)
# 清零最低位的1
bits &= (bits - 1)
dfs()
return count