剑指offer系列-面试题56 - I. 数组中数字出现的次数 (python)

1. 题目

一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。

2. 解题思路

详情见 数组中数字出现的次数

需要知道的是,数字 a 异或 a 的结果是0,而0与任何数异或的结果是那个数本身。

如果数组中只有1个只出现一次的数字

那么对数组中的元素不断进行异或即可,因为其他数字都是成对出现的,这些数字异或之后都会是0,所以最后异或的结果就是这个只出现了1次的数字。

但是现在是两个只出现一次的数字。

将数组分为两部分

这两个只出现1次的数字分别位于两个子数组的中,而且成对出现的数必须要同一子数组中。

步骤:
1)先对所有数字进行一次异或,得到两个出现一次的数字的异或值。
2)在异或结果中找到任意为 1 的位。
3)根据这一位对所有的数字进行分组。
4)在每个组内进行异或操作,得到两个数字。

3. 代码实现

3.1 分组异或

class Solution:
    def singleNumbers(self, nums: List[int]) -> List[int]:
        ret = functools.reduce(lambda x, y: x ^ y, nums) # 1.对整个数组异或
        div = 1 
        while div & ret == 0: # 2.找到为1的位
            div <<= 1
        a, b = 0, 0
        for n in nums:
            if n & div: # 3.根据这一位是否为1对原数组中的元素进行分组异或
                a ^= n
            else:
                b ^= n
        return [a, b]

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/solution/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

4. 总结

只能说看完了这个题之后,发现奇怪的知识又增加了。O(∩_∩)O

5. 参考文献

[1] 剑指offer丛书
[2] 剑指Offer——名企面试官精讲典型编程题
[3] 数组中数字出现的次数

猜你喜欢

转载自blog.csdn.net/besmarterbestronger/article/details/106480667