題目一:
一個整型數(shù)組里除了兩個數(shù)字之外,其他的數(shù)字都出現(xiàn)了兩次。請寫程序找出這兩個只出現(xiàn)一次的數(shù)字。時間復(fù)雜度為O(n), 空間復(fù)雜度O(1)。
思路:
這道題比較難,需要分步驟考慮,假設(shè)題目為只有一個數(shù)字出現(xiàn)了一次,其他的出現(xiàn)兩次,那么可以通過異或來得到結(jié)果,相同的兩個數(shù)字異或結(jié)果為0,所以說當(dāng)逐個異或之后,得出的結(jié)果為就為只出現(xiàn)一次的結(jié)果。
下面考慮,如何能夠把一個數(shù)組分成兩個每個里面只有一個數(shù)字出現(xiàn)一次,其余的都出現(xiàn)兩次的子數(shù)組。思路如下:將該數(shù)組異或按位異或,那么其結(jié)果一定不為0,既然不為0一定至少有一位不為0。從右到左,取出第一個不為0的位置,說明那兩個不同的只出現(xiàn)一次的值,在這位一定不同,所以按照這個位置上數(shù)字為1的是一個子數(shù)組,為0的為另一個子數(shù)組,然后在分別求出每個子數(shù)組里的出現(xiàn)一次的數(shù)字,即可解決這道題。
代碼實現(xiàn):
# -*- coding:utf-8 -*-
class Solution:
# 返回[a,b] 其中ab是出現(xiàn)一次的兩個數(shù)字
def FindNumsAppearOnce(self, array):
# write code here
#特殊情況
if len(array)<2:
return None
#一般情況
#得出異或的結(jié)果
Result = 0
for num in array:
Result ^=num
#得到結(jié)果中不為1的位置
index1 = self.FirstOne(Result)
#按照索引位置10不同分為兩個子數(shù)組
res1 = 0
res2 = 0
for nums in array:
if self.IsBit1(nums,index1):
res1 ^= nums
else:
res2 ^= nums
return [res1,res2]
#找到從右邊起第一個不為0的位置
def FirstOne(self,num):
index = 0
while (num&1==0 and index < 32):
num = num >> 1 #右移一位
index +=1
print("enter")
return index
#判斷對應(yīng)位置是否為1
def IsBit1(self,num, index):
num = num >> index #右移index位
return (num&1)
提交結(jié)果:
題目二:
在一個數(shù)組 nums 中除一個數(shù)字只出現(xiàn)一次之外,其他數(shù)字都出現(xiàn)了三次。請找出那個只出現(xiàn)一次的數(shù)字。
思路:
利用字典
代碼實現(xiàn):
class Solution:
def singleNumber(self, nums: List[int]) -> int:
#使用字典來完成操作
dicNum = {}
for i in nums:
if i not in dicNum:
dicNum[i] =1
else:
dicNum[i] +=1
for key in dicNum:
if dicNum[key]==1:
return key
提交結(jié)果: