元素依次进栈,若重复出现则出栈,最后输出字典余下的键即为不重复的数字
# -*- coding:utf-8 -*- class Solution: # 返回[a,b] 其中ab是出现一次的两个数字 def FindNumsAppearOnce(self, array): # write code here hashtable={} for i,num in enumerate(array) : if num in hashtable : del hashtable[array[i]] else: hashtable[num]=i return hashtable.keys()
# -*- coding:utf-8 -*- class Solution: # 返回[a,b] 其中ab是出现一次的两个数字 def FindNumsAppearOnce(self, array): # write code here import collections c = collections.Counter(array) list = [] for k in c: if c[k] == 1: list.append(k) return list
# -*- coding:utf-8 -*- class Solution: # 返回[a,b] 其中ab是出现一次的两个数字 def FindNumsAppearOnce(self, array): # write code here import collections c = collections.Counter(array) for k in c: if c[k] == 1: return k我使用案例代入,发现:
思路:先排序,则相同的数字一定相连。遇到下一个数相同,i+2,否则i即为只出现一次的数,i+1。 class Solution: # 返回[a,b] 其中ab是出现一次的两个数字 def FindNumsAppearOnce(self, array): # write code here array.sort()#先排序 res = [] i = 0 while i < len(array): if i == len(array)-1 and array[i-1] != array[i]:#末尾位置的情况 res.append(array[i]) i += 1 elif array[i] != array[i + 1]: res.append(array[i]) i += 1 else:#遍历到两个相同的数i+2 i += 2 return res
# -*- coding:utf-8 -*- class Solution: # 返回[a,b] 其中ab是出现一次的两个数字 def FindNumsAppearOnce(self, array): flag=[] re=[] for i in range(len(array)): if array[i] not in flag: if array[i]in array[i+1:len(array)+1]: flag.append(array[i]) else: re.append(array[i]) return re # write code here
def FindNumsAppearOnce(self, array): # write code here return(list(filter(lambda i:array.count(i)==1,array)))
利用字典: class Solution: # 返回[a,b] 其中ab是出现一次的两个数字 def FindNumsAppearOnce(self, array): (2128)# write code here if not array: return [] dit=dict() li=[] for num in array: if num in dit: dit[num]+=1 else: dit[num]=1 for k,v in dit.items(): if v==1: li.append(k) return li
class Solution: # 返回[a,b] 其中ab是出现一次的两个数字 def FindNumsAppearOnce(self, array): (2128)# write code here dic = dict() for i in range(len(array)): if array[i] in dic: dic[array[i]] += 1 else: dic[array[i]] = 1 res = [] for key, value in dic.items(): if value == 1: res.append(key) return res
# -*- coding:utf-8 -*- """ 异或操作 p xor q = q xor p (p xor q) xor r = p xor (q xor r) p xor 0 = p 位运算 """ class Solution: (1250)# 返回[a,b] 其中ab是出现一次的两个数字 def FindNumsAppearOnce(self, array): if not array: return [] res_xor_all = 0 # 相同的数字全部抵消,不同的数字使得结果至少某一位为1 for a in array: res_xor_all ^= a (1251)# 从右往左,第一个1的位置 index = self.find_first_one(res_xor_all) res1 = 0 res2 = 0 for a in array: # 元素第index位是1的一组,不是1的一组 if self.is_group(a,index): res1 ^= a else: res2 ^= a return [res1, res2] def find_first_one(self, a): index = 0 while a & 1 == 0: a = a >> 1 index += 1 return index def is_group(self, a, index): return a >> index & 1 s = Solution() ans = s.FindNumsAppearOnce([1,2,5,2]) print(ans)
class Solution: def FindNumsAppearOnce(self, array): lst1 = [] lst2 = [] def wBin(num): str2 = list(bin(num)) str1 = str2[::-1] for i in range(len(str1)): if str1[i] == '1': return i def OnlyNum(lstS): lst0 = lstS num1 = 0 for i in range(len(list(lst0))): num1 = num1^lst0[i] return num1 Bkey = wBin(OnlyNum((array))) for i in range(len(array)): if wBin(array[i]) == Bkey: lst1.append(array[i]) else: lst2.append(array[i]) return OnlyNum(lst1),OnlyNum(lst2)
# -*- coding:utf-8 -*- class Solution: # 返回[a,b] 其中ab是出现一次的两个数字 def FindNumsAppearOnce(self, array): L = [] for n in array: if n in L: L.remove(n) else: L.append(n) return L //核心思想,有就删除,没有就加入。剩到最后的就是落单的两个。
class Solution: # 返回[a,b] 其中ab是出现一次的两个数字 def FindNumsAppearOnce(self, array): # write code here dict1={} for i in array: l1=array.count(i) if i not in dict1: dict1[i]=l1 list1=[] for key,value in dict1.items(): if value==1: list1.append(key) return list1采用的空间换时间的方法,计算每个数字出现的次数,然后将出现次数为1的键拿出来
# -*- coding:utf-8 -*- class Solution: # 返回[a,b] 其中ab是出现一次的两个数字 def FindNumsAppearOnce(self, array): #已知: 整型数组中只出现一次的数字,可以用异或来解决 #那么当有两个只出现一次的数字时,数组异或的最终结果将是这两个数字的异或结果 #设数组的异或结果的二进制最后一位1是第n位(为什么选1,因为异或运算只有位上数值不同才会得到1) #根据第n位的二进制值来将数组划分为两部分,而这两个数字分布于两个部分 #解题步骤 #1.获取数组异或结果 #2.找到异或结果二进制最后一个1的位置 #3.将数组按该位置划分成两部分 #4.两部分分别异或得到两个只出现一次的数字 #1.获取数组异或结果 xor = array[0] for val in array[1:]: xor ^= val print(xor) #2.获取二进制1的位置 loc = 0 for val in bin(xor)[::-1]: if val=="1": break loc += 1 print(loc) #3.数组划分和异或同时进行 flag1 = True flag2 = True for val in array: if bin(val)[-(loc+1)]=='1': if flag1: xor1 = val flag1 = False else: xor1 ^= val else: if flag2: xor2 = val flag2 = False else: xor2 ^= val return [xor1, xor2]
class Solution { public: void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) { if(data.size()<2) return ; int size=data.size(); int temp=data[0]; for(int i=1;i<size;i++) temp=temp^data[i]; if(temp==0) return ; int index=0; while((temp&1)==0){ temp=temp>>1; ++index; } *num1=*num2=0; for(int i=0;i<size;i++) { if(IsBit(data[i],index)) *num1^=data[i]; else *num2^=data[i]; } } bool IsBit(int num,int index) { num=num>>index; return (num&1); } };
可以用位运算实现,如果将所有所有数字相异或,则最后的结果肯定是那两个只出现一次的数字异或的结果,所以根据异或的结果1所在的最低位,把数字分成两半,每一半里都还有只出现一次的数据和成对出现的数据
这样继续对每一半相异或则可以分别求出两个只出现一次的数字