位运算
写在前面:
1. 计算一个数的2二进制位个数:
count = 0
while(x!=0): x &= x-1 count+=1
或者:
count = bin(x).count('1')
2. 除法和求余数的方法
x / 2 is x >> 1 and x % 2 is x & 1
201. 数字范围按位与
给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。
示例 1:
输入: [5,7]
输出: 4
示例 2:
输入: [0,1]
输出: 0
思路:
n的二进制位比m二进制最左边的1高时,&的结果必然为0;
由这个思想启发,二进制最高位相同时,这个1会保存,然后比较右一位,相同也保留...
所以只需要m n 同时右移到相等时 m n的值就是&后能保留的位数,然后左移回来就是最后的值。
解法:
class Solution:
def rangeBitwiseAnd(self, m: int, n: int) -> int:
count = 0
while(m!=n):
m>>=1
n>>=1
count+=1
return n<<count
338. 比特位计数
给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。
示例 1:
输入: 2
输出: [0,1,1]
示例 2:
输入: 5
输出: [0,1,1,2,1,2]
思路1:暴力。
public class Solution { public int[] countBits(int num) { int[] ans = new int[num + 1]; for (int i = 0; i <= num; ++i) ans[i] = popcount(i); return ans; } private int popcount(int x) { int count; for (count = 0; x != 0; ++count) x &= x - 1; //zeroing out the least significant nonzero bit return count; } }
思路2:动态规划:即当前的数和其一半数有一个关系:要么位数相等(偶数),要么位数差1(奇数)。

class Solution:
def countBits(self, num: int) -> List[int]:
dp = [0]*(num+1)
for i in range(1, num+1):
dp[i] = dp[i>>1] + (i&1) # x / 2 is x >> 1 and x % 2 is x & 1
return dp
231. 2的幂

class Solution:
def isPowerOfTwo(self, n: int) -> bool:
return n>0 and not(n&(n-1))
342. 4的幂
class Solution:
def isPowerOfFour(self, num: int) -> bool:
if num<0 or num&(num-1): return False # 用来判断是不是2的幂
return num%3==1 # 是2的幂的基础上,再判断是不是4的幂
371. 两整数之和
不使用运算符 + 和 - ,计算两整数 a 、b 之和。
思路:这个解释得不错,哈哈。
405. 数字转换为十六进制数
给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用 补码运算 方法。
注意:
十六进制中所有字母(a-f)都必须是小写。
十六进制字符串中不能包含多余的前导零。如果要转化的数为0,那么以单个字符'0'来表示;对于其他情况,十六进制字符串中的第一个字符将不会是0字符。
给定的数确保在32位有符号整数范围内。
不能使用任何由库提供的将数字直接转换或格式化为十六进制的方法。
例如: 26:1a -1:ffffffff
class Solution:
def toHex(self, num: int) -> str:
if num==0: return "0"
mp = "0123456789abcdef"
res = ''
for i in range(8):
c = num%16
res = mp[c]+res
num = num>>4
return res.lstrip('0')

浙公网安备 33010602011771号