珍宝鸭的力扣练习(3):位运算合集

题目1: 二进制中1的个数

请实现一个函数,输入一个整数(以二进制串形式),输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 ‘1’。

题解:判断 n 最右一位是否为 1 ,根据结果计数。
将 n 右移一位(本题要求把数字 n 看作无符号数,因此使用 无符号右移 操作)。

class Solution(object):
    def hammingWeight(self, n):
        res = 0
        while n:
            res += n & 1
            n >>= 1
        return res

方法二:与2^i比较。

var hammingWeight = function(n) {
    let ret = 0;
    for (let i = 0; i < 32; i++) {
        if ((n & (1 << i)) !== 0) {
            ret++;
        }
    }
    return ret;
};

题目2:只出现一次的数(别的2次)

个整型数组 nums 里除1个数字之外,其他数字都出现了两次。请写程序找出这个只出现一次的数字。
要求时间复杂度是O(n),空间复杂度是O(1)。

class Solution(object):
    def singleNumbers(self, nums):
        result=0
        for n in nums:
            result^=n
        return result

题目3:2个只出现一次的数(别的2次)

个整型数组 nums 里除2个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。
要求时间复杂度是O(n),空间复杂度是O(1)。

题解:
如果我们可以把所有数字分成两组,使得:
1.两个只出现一次的数字在不同的组中;
2.相同的数字会被分到相同的组中

那么对两个组分别进行异或操作,即可得到答案的两个数字。
在异或和x中若有一位x_i==1,则表示两个只出现一次的数在此位置不等,则根据此位可分为两组。
我们拿到序列的异或和 x 之后,对于这个「位」是可以任取的,只要它满足 x_i = 1。但是为了方便,这里的代码选取的是「不为 0 的最低位。

class Solution(object):
    def singleNumbers(self, nums):
        h=0
        for n in nums:
            h^=n
        div = 1
        while div & h == 0:
            div <<= 1
        a, b = 0, 0
        for n in nums:
            if n & div:
                a ^= n
            else:
                b ^= n
        return [a, b]

题目3: 只出现一次的数(别的3次)

在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。
输入:nums = [3,4,3,3]
输出:4

题解:假设不存在这个 single number,那么 nums 中所有元素的二进制形式加起来之后,每一位必然都可以被 3 整除。因为每个数字都出现了三次,那么它们的二进制形式每一位也都出现了三次,那加起来之后每一位当然可以被 3 整除了。所以找除以3不等于0的位数就可以了。

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        lst=[0 for _ in range(32)]
        for n in nums:
            for i in range(len(lst)-1,-1,-1):
                lst[i]+=n&1
                n>>=1

        bit_result=[1 if n%3 else 0 for n in lst]
        result=0
        bit=1
        for i in range(len(bit_result)-1,-1,-1):
            result+=bit*bit_result[i]
            bit*=2
        return result
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值