题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
思路:
1. 从头到尾依次异或数组中的每个数字,找到结果数字中第一个为1的位置,记为第n位。
2.以第n位是不是1为标准把原数组中的数字分成两个数组,第一个子数组中每个数字的第n位都是1,第二个子数组中每个数字的第n位都是0。这样每个子数组包含一个只出现一次的数字,而其他数字都成对出现两次。
3. 在每个子数组中,从头到尾依次异或数组中的数字,最终的结果就是子数组中只出现一次的数字。
# -*- coding:utf-8 -*-
class Solution:
# 返回[a,b] 其中ab是出现一次的两个数字
def FindNumsAppearOnce(self, array):
# write code here
if not array:
return None
resultExclusiveOR = 0
for i in range(len(array)):
resultExclusiveOR ^=array[i]
indexOf1 = self.FindFirstBitIs1(resultExclusiveOR)
num1 = num2 = 0
for i in range(len(array)):
if self.IsBit1(array[i], indexOf1):
num1 ^= array[i]
else:
num2 ^= array[i]
return [num1, num2]
#找到最右边是1的位
def FindFirstBitIs1(self, num):
indexBit = 0
while num&1 == 0:
num = num>>1
indexBit+=1
return indexBit
#判断num从右到左第IndexOf1位是不是1
def IsBit1(self, num, indexOf1):
num = num>>indexOf1
return (num&1)
题目描述:
在一个数组中除了一个数字只出现一次外,其他数字都出现了三次,请找出那个只出现一次的数字。
思路:
如果一个数字出现了三次,那么它的二进制的每一位也出现三次。如果把所有出现三次的数字的二进制表示的每一位都分别加起来,那么每一位的和都能被3整除。由于python中的二进制保存的不是补码,所以正负数要分开讨论。这个方法比较慢。
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return None
nums_p = []
nums_n = []
for i in range(len(nums)):
if nums[i]>=0:
nums_p.append(nums[i])
else:
nums_n.append(-nums[i])
bitSum_p = [0]*32
for i in range(len(nums_p)):
bitMask = 1
for j in range(31, -1, -1):
bit = nums_p[i] & bitMask
if bit!=0:
bitSum_p[j]+=1
bitMask = bitMask<<1
result_p = 0
for i in range(32):
result_p = result_p<<1
result_p+=bitSum_p[i]%3
bitSum_n = [0]*32
for i in range(len(nums_n)):
bitMask = 1
for j in range(31, -1, -1):
bit = nums_n[i] & bitMask
if bit!=0:
bitSum_n[j]+=1
bitMask = bitMask<<1
result_n = 0
for i in range(32):
result_n = result_n<<1
result_n+=bitSum_n[i]%3
result_n = -result_n
return(result_n+result_p)
思路二:利用python中的set
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
return (3*sum(set(nums))-sum(nums))//2