只出现一次的数字系列

只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

用内置函数统计就是最赖皮的:

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        for n in nums:
            if nums.count(n) == 1:
                return n

但是上面的方法耗时太严重,最快的就是异或运算啦!出现两次的元素异或后为0,最后的运算结果就是只出现过一次的。

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        res = 0
        for n in nums:
            res = res ^ n
        return res

官方代码也是异或,只写了一行,真简洁👍

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        return reduce(lambda x, y: x ^ y, nums)

只出现一次的数字Ⅱ

给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。

赖皮且无意义解法,耗时是真的多!

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        for n in nums:
            if nums.count(n) == 1:
                return n

耗时结果
评论区的数学/电路大佬靠着强大的数学能力,利用与或非等将出现三次的元素运算为0,实在是妙!
一开始a = 0, b = 0;

x第一次出现后,a = (a ^ x) & ~b的结果为 a = x, b = (b ^ x) & ~a的结果为此时因为a = x了,所以b = 0。

x第二次出现:a = (a ^ x) & ~b, a = (x ^ x) & ~0, a = 0; b = (b ^ x) & ~a 化简, b = (0 ^ x) & ~0 ,b = x;

x第三次出现:a = (a ^ x) & ~b, a = (0 ^ x) & ~x ,a = 0; b = (b ^ x) & ~a 化简, b = (x ^ x) & ~0 , b = 0;所以出现三次同一个数,a和b最终都变回了0.

只出现一次的数,按照上面x第一次出现的规律可知a = x, b = 0;因此最后返回a.

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        a, b = 0, 0
        for n in nums:
            a = (a ^ n)& ~b
            b = (b ^ n)& ~a
        return a

在这里插入图片描述
快了两倍多,也没有使用额外空间,绝了!

只出现一次的数字Ⅲ

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

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

无用代码又有了。。。我有罪

class Solution:
    def singleNumber(self, nums: List[int]) -> List[int]:
        if len(nums) == 2:
            return nums
        res = []
        for n in nums:
            if nums.count(n) == 1:
                res.append(n)
        return res

在这里插入图片描述

就很耗时。

节省时间的话,还是以异或运算为基础,最后的结果则为两个只出现一次的元素的异或结果。任取一位为 1 的位数,两个数有一个为 1 ,一个为 0 。再次遍历,将 nums 分为两组,分别求出两个元素。

class Solution:
    def singleNumber(self, nums: List[int]) -> List[int]:
        if len(nums) == 2:
            return nums
        tem = 0
        for n in nums:
            tem ^= n
        pos = 1
        while pos&tem == 0:
            pos <<= 1
        a, b = 0, 0
        for n in nums:
            if n & pos:
                a ^= n
            else:
                b ^= n
        return [a, b]

在这里插入图片描述
绝了!

第一个只出现一次的字符

类似题,只不过是处理字符串

在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。

class Solution:
    def firstUniqChar(self, s: str) -> str:
        for char in s:
            if s.index(char) == s.rindex(char):
                return char
        return " "

字符串的内置函数就是比 list 丰富。

class Solution:
    def firstUniqChar(self, s: str) -> str:
        hashmap = collections.Counter(s)
        for i, char in enumerate(hashmap):
            if  hashmap[char] == 1:
                return char
        return  " "

使用哈希表,找到第一个频率为 1 的元素即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值