LeetCode-位运算-Medium

记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步




78-Subsets 子集

1.按次序插入
一开始ret内只有空数组
遍历ret内的每个数组 将第一个num插入
循环:
再一次 遍历ret内的每个数组 将第二个num插入
2.子集可以看做是挑选若干个num放入一个集合
可用二进制表示 1代表挑中 0代表不挑
n个数字 遍历1-2^n 将为1的位置的数字挑出放入
“”"

def subsets(nums):
    """
    :type nums: List[int]
    :rtype: List[List[int]]
    """
    ret = []
    ret.append([])
    for num in nums:
        l = []
        for tmp in ret:
            x = tmp[:]
            x.append(num)
            l.append(x)
        ret.extend(l)
    return ret

def subsets2(nums):
    """
    :type nums: List[int]
    :rtype: List[List[int]]
    """
    n = len(nums)
    ret = []
    ret.append([])
    if n==0:
        return ret
    for i in range(1,2**n):
        v = list((bin(i)[2:])[::-1])
        tmp=[]
        for j in range(len(v)):
            if v[j]=='1':
                tmp.append(nums[n-1-j])
        ret.append(tmp)
    return ret

137. Single Number II 只出现一次的数字 II

1.one,two,three分别代表出现了一次 两次 三次
位运算使得一个数在出现了三次后 被重置
2.通用方法 set去重 每个数乘3求和 减去原有和 剩下的为出现一次的数值的两倍

def singleNumber(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    one,two,three=0,0,0
    for num in nums:
        two = two | (one & num)
        one = one ^ num
        three = (one & two)
        two = two & ~three
        one = one & ~three
    return one

def singleNumber2(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    return int((sum(set(nums))*3-sum(nums))/2)

187. Repeated DNA Sequences 重复的DNA序列

思路都一样 以十个为一组 遍历
记录出现多次的返回

from collections import defaultdict
def findRepeatedDnaSequences(s):
    """
    :type s: str
    :rtype: List[str]
    """
    seqmap=defaultdict(int)
    for i in range(len(s)-9):
        subs = s[i:i+10]
        seqmap[subs]+=1
        
    res=[]
    for k in seqmap.keys():
        if seqmap[k]>1:
            res.append(k)
    return res

def findRepeatedDnaSequences2(s):
    """
    :type s: str
    :rtype: List[str]
    """
    one,ret = set(),set()
    for i in range(len(s)-9):
        subs = s[i:i+10]
        if subs in one:
            ret.add(subs)
        else:
            one.add(subs)
    return list(ret)

201. Bitwise AND of Numbers Range 数字范围按位与

与操作 只要出现一次0的位置那么那里永远是0
只要两个数的二进制位数不一致 那么从m->n的遍历过程 每一个位置必然会出现0 所以这种情况下答案一定是0
比如3(11)->6(110) 011&100&101&110=0
换而言之 我们只要关注两个数遍历过程中 高位不变的部分才是被保留下来的部分
所以 将两个数同时向右边做位移 当剩余的部分一直时这一部分就是被保留的高位数值部分 还原被移动的次数即可

def rangeBitwiseAnd(m, n):
    """
    :type m: int
    :type n: int
    :rtype: int
    """
    step=0
    while m!=n and m!=0:
        m>>=1
        n>>=1
        step+=1
    
    return m<<step

260. Single Number III 只出现一次的数字 III

有两个数不同 那么求取所有数的异或xor 等于不同的两个数a,b的异或
因为a<>b那么xor至少有一位等于1 而在这一位上a,b中一个等于0,一个等于1
所以可以将所有数根据这一位是否等于1 分为两组 一组包含了a,另一组包含了b
那么对这两组的数取分别都异或 一组为a 一组为b

def singleNumber(nums):
    """
    :type nums: List[int]
    :rtype: List[int]
    """
    xor,a,b,mask=0,0,0,1
    for num in nums:
        xor ^=num
    while xor&mask==0:
        mask<<=1
    for num in nums:
        if num&mask:
            a ^=num
        else:
            b ^=num
        
    return [a,b]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值