260、只出现一次的数字Ⅲ(2021-10-30)

目录

题目

思路和代码

 方法一:去重循环遍历统计次数

方法二:哈希映射

方法三:位运算


题目

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。

进阶:你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?

来源:力扣(LeetCode)
链接:原文链接

思路和代码

 方法一:去重循环遍历统计次数

 首先将数组用set()函数去重,根据原数组进行统计,将去重后得到的列表中出现2次的数字删除,直到去重后的列表长度为2。

注:复杂度不符合要求,需进一步优化

class Solution:
    def singleNumber(self, nums: List[int]) -> List[int]:
        i,j,ans = 0,0,0
        singlenum = list(set(nums))
        while len(singlenum) is not 2:
            for j in range(len(nums)):
                if nums[j] == singlenum[i]:
                    ans += 1
            if ans == 2:
                del(singlenum[i])
            else: 
                i += 1
            ans = 0
        return singlenum

方法二:哈希映射

用哈希映射统计数组中每一个元素出现的次数,再对哈希映射进行遍历,只出现了一次的数放入答案中即可。

class Solution:
    def singleNumber(self, nums: List[int]) -> List[int]:
        numsfreq = Counter(nums)
        return [num for num, occ in numsfreq.items() if occ == 1]

方法三:位运算

由a^a=0,0^b=b,推出,a^a^b=b。

由于题目所给数组中只有两个不同的数字出现一次,其他数字均出现两次,如果将整个数组进行异或运算,可得到a^b=c的结果。

而,c&(-c)可以得到c的二进制表示中为“1”的最低位,用lsb表示。若将整个数组与lsb进行与运算可以将整个数组分为两类,二进制表示中第lsb位是否为1,并且a与b不在同一类中。再分别将这两类中的数字进行异或运算,由于只有a,b只出现一次,因此异或后的结果就分别为a和b。

class Solution:
    def singleNumber(self, nums: List[int]) -> List[int]:
        xorsum = 0
        for num in nums:
            xorsum ^= num
        
        lsb = xorsum & (-xorsum)
        print("lsb=",lsb)
        type1 = type2 = 0
        for num in nums:
            if num & lsb:
                type1 ^= num
            else:
                type2 ^= num
        
        return [type1, type2]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值