记录刷题的过程。牛客和力扣中都有相关题目,这里以牛客的题目描述为主。该系列默认采用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)