leetcode 位运算

lc 461. 汉明距离

在这里插入图片描述

class Solution:
    def hammingDistance(self, x: int, y: int) -> int:
        z = x^y
        cnt = 0
        while z!=0:
            if z&1==1:
                cnt+=1
            z=z>>1
        return cnt
  • 区分整数和位运算的关系,一次位运算把所有的不同全拿出来了。
  • 而后只要不是0,int或者位都可以反正是所有,就去拿之后右移。

136. 只出现一次的数字

在这里插入图片描述

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        length = len(nums)
        res = nums[0]
        for i in range(1,length):
            res = res^nums[i]
        return res

lc 260. 只出现一次的数字 III

在这里插入图片描述

class Solution:
    def singleNumber(self, nums: List[int]) -> List[int]:
        length = len(nums)
        xor = 0
        for i in range(length):
            xor ^= nums[i]
        # 移动如果有一位是就停了,不是全部位相等才行
        mask_bit = 1
        # 如果是0即相同就移动,一般都是按照0来判断
        while mask_bit & xor==0:
            mask_bit = mask_bit<<1  
        a=0
        b=0
        for i in range(length):
            if mask_bit&nums[i]==0:
                a = a^nums[i]
            else:
                b = b^nums[i]
        return [a,b]
  • 与为0只要有一位不是就不是了。
  • 分组,一般都以0判断。

lc 268. 丢失的数字

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
    # 法1
        adict ={k:None for k in range(len(nums)+1) }
        for i in nums:
            adict[i] = 1
        for k,v in adict.items():
            if v is None:
                return k
        # 法2,因为有数字没序号,所以让missing先去占一个位置
        missing = len(nums)
        for i, num in enumerate(nums):
            missing ^= i ^ num
        return missing
  • 缺失的时候直接去让序号和内容一起位运算即可

lc 338. 比特位计数

在这里插入图片描述

class Solution:
    def countBits(self, n: int) -> List[int]:
        res = []
        for i in range(n + 1):
            res.append(self.count(i))
        return res
    
    def count(self, num):
        if num == 0:
            return 0
        if num % 2 == 1:
            return self.count(num - 1) + 1
        return self.count(num // 2)
  
# 优化
class Solution:
    def countBits(self, n: int) -> List[int]:
        self.memo = [0] * (n + 1)
        res = []
        for i in range(n + 1):
            res.append(self.count(i))
        return res
    
    def count(self, num):
        if num == 0:
            return 0
        if self.memo[num] != 0:
            return self.memo[num]
        if num % 2 == 1:
            res = self.count(num - 1) + 1
        else:
            res = self.count(num // 2)
        self.memo[num] = res
        return res
  • 要返回一个数,如果是余2等于1则继续减去一个,结果+1,否则直接对半砍掉。能被2整除只有相同位数。

lc 190. 颠倒二进制位

在这里插入图片描述

class Solution:
    def reverseBits(self, n: int) -> int:
        res,power = 0,31
        while n:
            res |= (n&1)<<power
            power -= 1
            n=n>>1
        return res
  • int 是32位,要给他怼到头,与1是取最后一位和%数一样

lc 231. 2 的幂

在这里插入图片描述

class Solution:
    def isPowerOfTwo(self, n: int) -> bool:
        return n > 0 and n & (n - 1) == 0
  • 容易想到整个数里只有一个是1,所以减1之后相与一定是0.

lc 693. 交替位二进制数

在这里插入图片描述

class Solution:
    def hasAlternatingBits(self, n: int) -> bool:
        a = n^(n>>1)
        return a&(a+1)==0
  • 先错开一位取亦或,除了最高位如果都不同的话亦或后都变成1,所以加1之后进位都是0.
  • 再看最高位,如果原来是1,被进位后最高位是0,如果原来是0被进位后是1,所以求与如果是交替(注意是交替不相邻有)的话会是0。

lc 342. 4的幂

在这里插入图片描述

class Solution:
    def isPowerOfFour(self, n: int) -> bool:
        mi = 0
        while 4 ** mi <= n:
            if n == 4 ** mi:
                return True
            mi += 1
        return False

  • 4的幂运算本身就够快了,别优化了。

lc 318. 最大单词长度乘积

在这里插入图片描述

class Solution:
    def maxProduct(self, words: List[str]) -> int:
        max_res = float('-inf')
        length = len(words)
        bit_list = [0]*length
        for i in range(length):
            for j in words[i]:
                bit_list[i] |= 1<<(ord(j)-ord('a'))
        for i in range(length-1):
            for j in range(i+1,length):
                if bit_list[i]&bit_list[j]==0:
                    max_res = max(max_res,len(words[i])*len(words[j]))
        if max_res == float('-inf'):
            max_res =0
        return max_res
        
        # 通俗方法
        def pending_str(s1, s2):
            return len([x for x in s1 if x in s2]) == 0
        max = 0
        for i in range(len(words) - 1):
            for j in range(i + 1, len(words)):
                if pending_str(words[i],words[j]):
                    if max < len(words[i]) * len( words[j]):
                        max = len(words[i]) * len( words[j])
        return max
  • 因为要完全不一样,所以才有上面的位运算的说法,每次挪一位往上加,然后求与,如果为0说明完全不一样,注意这个题是要求完全不一样。
  • 位运算因为对字符串重新编码了,然后进行了一次计算,所以速度特别的快。

lc 476. 数字的补数

在这里插入图片描述

class Solution:
    def findComplement(self, num: int) -> int:
        n=bin(num)[2:]#转二进制,从索引2取到最后,因为转二进制后前面会有0b,需要去掉
        c=""
        d=0
        while d<len(n):
            if n[d]=="0":#当n[索引]为"0",就变成1
                c=c+"1"
            else: 
                c=c+"0"                                                     
            d+=1
        e=int(c,2)#转十进制
        return e
  • 比较有通用性,bin先求出来二进制,从2后面取。这个结果列表是str的。
  • while想从头开始取写个变量递增就可以。

lc 371 不用+,-计算两个数的和

public int getSum(int a, int b) {
    if (a == 0) return b;
    if (b == 0) return a;

    while (b != 0) {
        int carry = a & b; //将存在进位的位置置1
        a = a ^ b; // 计算无进位的结果
        b = carry << 1;
    }
    
    return a;
}
  • 亦或运算得到的是不带进位的和。
  • 与得到的是进位位需要右移。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值