位运算--找出只出现一次的数字

‘’’
找出唯一一个只出现过一次的数字。
一个非连续的递增数组,所有的数字会连续出现两遍,只有一个数字出现一遍,请找出这个数字
输入:1,1,2,2,5,6,6,7,7
输出:5
同力扣136,+输入转换

“出现多次”:只有出现偶数次,才可以用异或
‘’’

data = input()
data += ','
num = 0
h = 0
for i in range(len(data)):
    if data[i] != ',':
        num = num * 10 + int(data[i])
    else:
        h ^= num
        num = 0
print(h)
#时间O(N),空间O(1)

力扣137:
‘’'给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。

法1:位运算,需要2个计数的bitmap, 时间O(N),空间O(1)
法2: hashmap, 时间O(N),空间O(N)
法3:hashset, 时间O(N), 空间O(N)
‘’’

from typing import List
class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        #第一次出现:改变once,对twice无影响
        #第二次出现,复原once,改变twice
        #第三次出现,对once无影响,复原twice
        #如果还有,又一轮:
        #第四次出现,改变once,对twice无影响
        #第五次出现,复原once,改变twice
        #第六次输出,对once无影响,复原twice
        #...
        once = 0
        twice = 0
        for i in nums:
            once = ~twice & (once ^ i)
            twice = ~once & (twice ^ i)
        return once
        #return once, twice
    #法1 也可以用来找出 出现1次,出现2次(但是,这两种情况的数字要求只有一个)
    def singleNumber_2(self, nums: List[int]) -> int:
        from collections import Counter
        hashmap = Counter(nums)
        for k,v in hashmap.items():
            if v < 2:
                return k #只有1个数出现了一次
    def singleNumber_3(self, nums: List[int]) -> int:
        return (3 * sum( set(nums) ) - sum(nums)) // 2

力扣260
‘’‘给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。
‘’’

from typing import List
class Solution:
    def singleNumber(self, nums: List[int]) -> List[int]:
        bitmap = 0
        for i in nums:
            bitmap ^= i  #bitmap 记录2个数字的差
        diff = bitmap & (-bitmap) # 计算2个数字的差异,最后一位,只来自2个数字中的一个!
        #diff仅保留bitmap中最右边不为0的一位,其余均为0, 而这一位,必然来自两个仅出现一次的数字中的其中一个
        #diff用于帮助确认,两个仅出现一次的数字中的其中一个!
        #确认了一个,另一个通过bitmap就可以确定了!
        tmp = 0
        for i in nums:
            if i & diff:
                tmp ^= i #tmp存的是,只出现1次的2个数中,diff 上为1的那个
        return [tmp, bitmap ^ tmp]

    def singleNumber_2(self, nums: List[int]) -> List[int]:
        from collections import Counter
        hashmap = Counter(nums)
        return [k for k,v in hashmap.items() if v < 2] #语法:if在后!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值