【LeetCode】【137. Single Number II】(python版)

给定一个整数数组,除了一个元素出现一次外,其余元素均出现三次。设计线性时间复杂度且不使用额外空间的算法找到这个唯一出现一次的元素。本文介绍了三种解决方案,包括位运算方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description:

Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

Example 1:

Input: [2,2,3,2]
Output: 3

Example 2:

Input: [0,1,0,1,0,1,99]
Output: 99

思路:

本题在Single Number的基础上略微改变,仍然可以按照方法一求解,对于方法二,只需要改成3*(a+b+c) - (a+b+a+b+a+b+c) = 2 * c,依然可以使用。但由于题目在线性复杂度的要求上提出不使用额外空间,因此重点在于使用位运算的第三种方法。

下面重新分析:

(:以下方法非本人原创,但许多解释过于简单,有些涉及到真值表或卡诺图的化简,这里尽量用最简单的方法解释)

在原题中,我们采用一个变量one来记录数字a是否出现过,计算one = one ^ a,出现一次就记录数值,出现两次数值清零,以one是否为零能很清晰地判断数字出现的次数。在本题中,如果仍采用这种方法,无法判断当one不为0时,数字出现了一次还是三次。因此采用one来记录出现了一次的数字,用two记录出现了两次的数字,用three记录出现了三次的数字。

  • 只有当two1,并且当前又出现一次数字a时,才表示数字出现了3次,所以有

    在这里插入图片描述

  • 数字出现2次(two==1)只有当上一时刻one1,并且当前又出现一次数字a,或者当上一时刻two1,并且当前出现数字不为a时,并且当数字出现了3次之后,需要将two的数值清零,所以有

    在这里插入图片描述

  • 数字出现1次(one==1),只有当上一时刻one0,且当前又出现一次数字a,同样当数字出现了3次后,需要将one的数值清零

    在这里插入图片描述

  • 接下来还有一个问题,三个更新公式的先后顺序如何?首先由于one、two都要依赖当前three的数值来判断当前是否清零,所以three的更新应该在最前面;其次,two的更新依赖于上一时刻的one,所以two的更新应该在one前面

  • 题目要求找出只出现过一次的数字,即one==1

总体代码如下:

    def singleNumber(self, nums: List[int]) -> int:
        one = two = 0
        for a in nums:
            three = two & a
            two = (two & ~a) | (one & a) & (~three)
            one = one ^ a & (~three)
        # 假如特殊的数不确定出现了一次还是两次
        # return one | two
        # 假如特殊的数确定只出现了一次
        return one 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值