Leetcode题目中有一类题目涉及到位运算。下面给大家总结一下这一类题目的做法。
(未写完待续)
1. 异或位运算
异或运算想必大家一定有所耳闻。
两个数字异或:a^b运算方式是将 a 和 b 的二进制每一位进行运算,如果同一位的数字相同则为 0,不同则为 1。
小性质:任何数和本身异或结果为 0,任何数和 0 异或结果为其本身
Leetcode中相关题目:
- Leetcode 136. 只出现一次的数字
- Leetcode 137. 只出现一次的数字 II
- Leetcode 260. 只出现一次的数字 III (面试题56 - I. 数组中数字出现的次数)
- Leetcode 645. 错误的集合
Leetcode 136. 只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
不用多说直接异或整个集合,最终的答案就是要找的数字
class Solution:
def singleNumber(self, nums: List[int]) -> int:
res = 0
for num in nums:
res ^= num
return res
Leetcode 137. 只出现一次的数字 II
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。
方法1:利用python的set消除重复数字后乘以3与本身加和做差
3(a+b+c+…x) - (3a + 3b +… + x) = 2x
class Solution:
def singleNumber(self, nums):
return (3 * sum(set(nums)) - sum(nums)) // 2
方法2:状态转移法
出现三次的数字该位置上的1对3取余数一定是0,所以相当于各个位置上的1的个数对3取余以后剩下的即为单个的数字。如下图:图片来源
各二进制位的 位运算规则相同 ,因此只需考虑一位即可。如下图所示,对于所有数字中的某二进制位 1的个数,存在 3 种状态,即对 3 余数为 0, 1, 2。所以我们使用三种状态来表示各个位置上的1的个数,各个状态转移关系如下图: (三种状态使用二进制要两位来表示)
状态转移真值表如下: Z Z Z为输入
将 X n e w X_{new} Xnew和 Y n e w Y_{new} Y