defswap_numbers(a, b): """ 使用异或运算交换两个数。 a = a ^ b # 第一步,a变量现在保存了a和b的异或结果 b = a ^ b # 第二步,由于a已经是a和b的异或结果,所以这一步b变为原来的a a = a ^ b # 第三步,a变为原来的b """ a = a ^ b b = a ^ b a = a ^ b return a, b
Single Number
这道题目要求我们找到一个数组中唯一出现一次的元素,其它元素都出现两次。我们可以使用异或运算来解决这个问题。
defsingle_number(nums: List[int]) -> int: """ 找出数组中只出现一次的元素。 利用异或运算的性质,将数组中的所有元素进行异或运算,最终的结果就是只出现一次的元素。 """ result = 0# 初始化结果为0 for num in nums: # 遍历数组中的每个元素 result ^= num # 将元素与result进行异或运算 return result # 返回结果
Single Number II
这道题目要求我们找出数组中唯一出现一次的元素,其它元素都出现三次。我们可以统计每个位上1出现的次数,如果某个位上1出现的次数不能被3整除,那么只出现一次的那个数在这个位上的值一定是1。
defsingle_number_ii(nums: List[int]) -> int: """ 找出数组中只出现一次的元素。 遍历32位整数的每一位,统计每一位上1出现的次数,最后根据1出现的次数还原出只出现一次的那个数。 """ result = 0# 初始化结果为0 for i inrange(32): # 遍历32位整数的每一位 sum = 0# 初始化sum为0,用于统计当前位上1出现的次数 for num in nums: # 遍历数组中的每个元素 sum += (num >> i) & 1# 统计当前位上1出现的次数 result ^= (sum % 3) << i # 根据1出现的次数还原出只出现一次的那个数 return result if result < 2**31else result - 2**32# 处理负数的情况
Single Number III
这道题目要求我们找出数组中唯一出现一次的两个元素。我们可以先计算所有元素的异或结果,再根据异或结果中的任意一个为1的位将所有元素分为两组,每组各包含一个只出现一次的元素。
defsingle_number_iii(nums: List[int]) -> List[int]: """ 找出数组中只出现一次的两个元素。 首先计算数组中所有元素的异或结果,然后根据异或结果中的任意一个为1的位将所有元素分为两组, 每组各包含一个只出现一次的元素,最后分别计算两组元素的异或结果。 """ diff = 0# 初始化diff为0,用于保存数组中所有元素的异或结果 for num in nums: # 计算数组中所有元素的异或结果 diff ^= num diff &= -diff # 获取diff中的最低位1 res1, res2 = 0, 0# 初始化两个结果变量 for num in nums: # 遍历数组中的每个元素,依据diff将元素分为两组 if num & diff == 0: # 第一组 res1 ^= num else: # 第二组 res2 ^= num return [res1, res2] # 返回两个只出现一次的元素
Number of 1 Bits
这道题目要求我们计算一个无符号整数的二进制表达式中数字位数为 ‘1’ 的个数。我们可以通过逐位检查或利用n&(n−1) 来快速移除最低位的1。
defhamming_weight(num: int) -> int: """ 计算一个无符号整数的二进制表达式中数字位数为 ‘1’ 的个数。 使用 n & (n - 1) 来快速移除最低位的1,从而实现快速计数。 """ count = 0# 初始化计数器为0 while num: # 循环直到num变为0 num &= num - 1# 利用 n & (n - 1) 来快速移除最低位的1 count += 1# 计数器加1 return count # 返回计数结果
Counting Bits
这道题目要求我们计算从 0 到 num 的所有数的二进制表达式中数字位数为 ‘1’ 的个数。我们可以利用动态规划的方法来解决这个问题。
defcount_bits(num: int) -> List[int]: """ 对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。 使用动态规划的方法,状态转移方程为:res[i] = res[i & (i - 1)] + 1。 """ res = [0] * (num + 1) # 初始化结果数组,长度为 num + 1 for i inrange(1, num + 1): # 从1开始计算到num的每个数的二进制表达式中数字位数为 ‘1’ 的个数 res[i] = res[i & (i - 1)] + 1# 利用动态规划的状态转移方程计算 res[i] return res # 返回结果数组