牛客-剑指offer系列题解:数组中只出现一次的数字

记录刷题的过程。牛客和力扣中都有相关题目,这里以牛客的题目描述为主。该系列默认采用python语言。
1、问题描述:
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
2、数据结构:
位运算

3、题解:
位运算 和力扣260题一样
力扣的136,137,645也是位运算,想练手位运算不妨做做

https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/solution/zhi-chu-xian-yi-ci-de-shu-xi-lie-wei-yun-suan-by-a/ 这里是引用

思路就是分组。

# -*- coding:utf-8 -*-
class Solution:
    # 返回[a,b] 其中ab是出现一次的两个数字
    def FindNumsAppearOnce(self, array):
        # write code here
        #如果两个数相同,那么这两个数的异或操作就等于0
        if len(array) < 2:
            return None
        #先逐个异或,寻找1
        twonum = None
        for num in array:
            if twonum == None:
                twonum =num
            else:
                twonum ^= num
        # 计算1出现的位置
        count = 0
        while twonum % 2 == 0:
            twonum = twonum >> 1 #等价于twonum //= 2
            count += 1
        #分组
        m = 1 << count
        firstnum,secondnum = None,None
        for num in array:
            if m & num == 0:
                if firstnum == None:
                    firstnum = num
                else:
                    firstnum = firstnum ^ num
            else:
                if secondnum == None:
                    secondnum = num
                else:
                    secondnum = secondnum ^ num
        return firstnum,secondnum

简化版:

# -*- coding:utf-8 -*-
class Solution:
    # 返回[a,b] 其中ab是出现一次的两个数字
    def FindNumsAppearOnce(self, array):
        # write code here
        ret = 0  # 所有数字异或的结果
        a = 0
        b = 0
        for n in array:
            ret ^= n
        # 找到第一位不是0的
        h = 1
        while(ret & h == 0):
            h <<= 1
        for n in array:
            # 根据该位是否为0将其分为两组
            if (h & n == 0):
                a ^= n
            else:
                b ^= n

        return [a, b]

4、复杂度分析:

时间复杂度:O(N)
空间复杂度:O(1)

发布了61 篇原创文章 · 获赞 10 · 访问量 2886

猜你喜欢

转载自blog.csdn.net/weixin_42042056/article/details/105762323