文章归档算法题解

leetcode-136. 只出现一次的数字

136. 只出现一次的数字

题目要求找出数组中只出现一次的数字。我首先想到用哈希表统计每个值的出现次数,再找出次数为 1 的那个值:

Python
class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        hs=dict()
        for i in nums:
            hs[i]=hs.get(i,0)+1
        for key in hs.keys():
            if hs[key]==1:
                return key

这里虽然写了两个 for 循环,但它们依次执行,并非嵌套,所以时间复杂度仍为 O(n)。不过哈希表需要 O(n) 的额外空间,不满足题目要求的常数空间。

要减少额外空间,可以使用异或运算。它逐位比较两个数:对应位不同,结果为 1;相同,结果为 0。下面几个性质正好适合这道题:

  1. 一个数与 0 异或,结果还是它本身,即 x^0=x。例如 9 的二进制为 1001,每一位与 0 异或后都不变,结果仍为 1001。

  2. 两个相同的数异或,结果为 0,即 x^x=0。例如 1001 与 1001 的各位都相同,异或后得到 0000。

  3. 异或满足交换律和结合律,因此 x^y^x=x^x^y,可以把相同的数放在一起抵消。

把数组中的所有数依次异或,成对出现的数字会抵消为 0,最后剩下的就是只出现一次的数字。整个过程只需一次遍历,时间复杂度为 O(n),额外空间为 O(1)。

Python
class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        res=0
        for i in nums:
            res=res^i
        return res
谢谢你读到这里。 ✧
搜索文章

输入关键词,找一篇想读的手记。

算法专题leetcode双指针经典练习题算法题解leetcode-1438. 绝对差不超过限制的最长连续子数组算法题解leetcode-179. 最大数算法题解leetcode-239. 滑动窗口最大值算法题解leetcode-136. 只出现一次的数字算法专题leetcode动态规划基础练习题算法专题leetcode二叉树基础练习题算法专题leetcode数组双指针练习题算法专题leetcode滑动窗口练习题算法专题leetcode链表双指针练习题算法题解洛谷-P1029 [NOIP 2001 普及组] 最大公约数和最小公倍数问题算法题解leetcode-1979. 找出数组的最大公约数算法题解洛谷-B3634 最大公约数和最小公倍数算法题解洛谷-P10424 [蓝桥杯 2024 省 B] 好数算法题解洛谷-P8716 [蓝桥杯 2020 省 AB2] 回文日期自动化脚本Dr.com校园网自动登录方案算法题解leetcode-2226. 每个小孩最多能分到多少糖果算法题解leetcode-2563. 统计公平数对的数目算法题解leetcode-1.两数之和算法题解洛谷-P8218 【深进1.例1】求区间和
在这座小岛上,慢慢找。ESC 关闭