LeetCode刷题——位运算(python语言)
一、位运算
1.1 与运算
全为1,才为1
1.2 或预算
有1,就是1
1.3 取反运算
1为0,0为1
1.4 异或运算
相同为0 ,相异为1
二、刷题
2.1 只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
**题解:**根据两个相同的数字异或运算为0,一个数字和0异或运算为原理啊
class Solution:
def singleNumber(self, nums: List[int]) -> int:
answer = 0
for item in nums:
answer ^= item
return answer
2.2 只出现一次的数字 II
给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
示例 1:
输入:nums = [2,2,3,2]
输出:3
示例 2:
输入:nums = [0,1,0,1,0,1,99]
输出:99
提示:
1 <= nums.length <= 3 * 104
-231 <= nums[i] <= 231 - 1
nums 中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次
进阶:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
**解法一:**哈希表统计,返回为一的
class Solution:
def singleNumber(self, nums: List[int]) -> int:
dictory = {}
for item in nums:
if item not in dictory:
dictory[item] = 0
dictory[item] += 1
for key,value in dictory.items():
if value==1:
return key
**解法二:**去重乘以三减去求和除以二
class Solution:
def singleNumber(self, nums: List[int]) -> int:
return int((3*sum(set(nums))-sum(nums))/2)
2.3 只出现一次的数字 III
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
进阶:你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?
示例 1:
输入:nums = [1,2,1,3,2,5]
输出:[3,5]
解释:[5, 3] 也是有效的答案。
示例 2:
输入:nums = [-1,0]
输出:[-1,0]
示例 3:
输入:nums = [0,1]
输出:[1,0]
提示:
2 <= nums.length <= 3 * 104
-231 <= nums[i] <= 231 - 1
除两个只出现一次的整数外,nums 中的其他数字都出现两次
**解法:**对每个元素求异或,最终结果difference为两个不同数字的异或。对-difference为每位取反加一,那么对他俩与运算,区分出两个元素的集合,分别对两个集合每位异或运算。得出结构
class Solution:
def singleNumber(self, nums: List[int]) -> List[int]:
difference = 0
for item in nums:
difference ^= item
difference &= -1 * difference
num1 = num2 = 0
for item in nums:
if(item&difference==0):
num1 ^= item
else:
num2 ^= item
return [num1,num2]
2.4 子集
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入:nums = [0]
输出:[[],[0]]
提示:
1 <= nums.length <= 10
-10 <= nums[i] <= 10
nums 中的所有元素 互不相同
**解法:**n长度的集合其子集个数为2的n次方,根据每个元素是否被选择,而已设置和集合长度大小相同的二进制数,位数为1代表选择,为0代笔没有选择。这样对每个数左移,乘以2,对2其余为真,放入列表。最终存储。
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
answer = []
for i in range(2**n):
item = []
for j in range(n):
if(i>>j)%2:
item.append(nums[j])
answer.append(item)
return answer
2.5 2 的幂
给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。
如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。
示例 1:
输入:n = 1
输出:true
解释:20 = 1
示例 2:
输入:n = 16
输出:true
解释:24 = 16
示例 3:
输入:n = 3
输出:false
示例 4:
输入:n = 4
输出:true
示例 5:
输入:n = 5
输出:false
提示:
-231 <= n <= 231 - 1
进阶:你能够不使用循环/递归解决此问题吗?
**解法:**首先2的幂指数一定大于零,整数是二的倍数二进制只有一个1,减1的话高位的1没有了,两者相与为0
class Solution:
def isPowerOfTwo(self, n: int) -> bool:
return n>0 and (n&(n-1))==0