我正在尝试解决一个问题,我给出了一个数组,例如[0,0,1,1,2,2,6,9,9,10],其中所有数字都是重复的两次,不包括一个数字,我需要返回不重复的数字。
我想这样做:
def findNumber(self, nums):
if (len(nums) == 1):
return nums[0]
nums_copy = nums[:]
for i in nums:
nums_copy.remove(i)
if i not in nums:
return i
else:
nums_copy.remove(i)
但是当它到达else语句时,会出现以下错误:
ValueError:list.remove(x):x不在列表中
i
位于nums_copy
时会发生这种情况,所以我不明白为什么在这种情况下会出现此错误?
答案 0 :(得分:10)
比初始方法更容易(也更有效)的方法是使用Counter
对象:
from collections import Counter
singlet = Counter(nums).most_common()[-1][0]
Counter
对象将创建一个类似字典的对象,其中的键是列表中的值,值是它们出现的次数。 most_common
方法将返回按降序排序的(value, count)
元组列表。
如果您不知道会有多少单身,您可以通过以下方式获取它们的列表:
[k for k, v in Counter(nums).items() if v == 1]
<强>复杂度:强>
我说我的顶级解决方案效率更高,因为您的原始实现会遍历您的列表,并且每个项目都会调用remove
和in
,这将使您获得类似O(n 2 )复杂性。在Counter实现中,Counter
对象的构造只进行一次遍历整个列表。 调用 @Stefan Pochman对此纠正了我:Python使用了Timsort算法在这种情况下非常有效(如果除了其中一个数字出现两次之外,列表实际上几乎已经完全排序了),那么它的复杂性约为O(n)。most_common
时可能会出现这种情况,所以我猜测复杂性是关于O(n log n)。
答案 1 :(得分:7)
您已nums_copy.remove(i)
,因此无法再次nums_copy.remove(i)
你可以这样做:
a = [0, 0, 1, 1, 2, 2, 6, 6, 9, 10, 10]
def get_single_instance(array):
d = {}
for item in a:
if item not in d:
d[item] = 1
else:
d[item] += 1
print d
for k, v in d.iteritems():
if v == 1:
return k
print get_single_instance(a)
结果:9
答案 2 :(得分:4)
最好的算法是使用XOR来查找奇数。
def find_number(nums):
s = 0
for n in nums:
s ^= n
return s
a = [0, 0, 1, 1, 2, 2, 6, 6, 9, 10, 10]
print(find_number(a))
答案 3 :(得分:2)
尝试此列表理解。它遍历每个元素并检查它是否重复,如果不重复,则让它保留在新列表中。然后它获取新列表的第0个元素:
a=[0, 0, 1, 1, 2, 2, 6, 6, 9, 10, 10]
[e for e in a if a.count(e)==1][0]
答案 4 :(得分:2)
如果数组已排序,我们可以在O(log n)
时间和O(1)
额外空格中找到答案。考虑重复的数字对从奇数或偶数索引开始,具体取决于单个元素的位置:
0 1 2 3 4 5 6 7 8 9 10
[0, 0, 1, 1, 2, 2, 6, 6, 9, 10, 10]
even indexes: x x x x
odd indexes: x
search: ^ (0 + 11) / 2 = 5
[2, 2] pair starting on even index
so the singleton must be ahead
^ (6 + 11) / 2 = 8
[9] singleton found in two steps!
答案 5 :(得分:1)
这是一种很长的做事方法。根据建议您可以使用nums_copy.remove(i)
,或者您可以使用count()
实现这种方式更为简单:
def findNumber(self, nums):
for i in nums:
val = nums.count(i)
if val == 1:
return i
这将返回单个号码。只要您没有多个值,此方法就可以了,如果是这样,它将只返回最后一个值。否则,您可以返回一个列表,该列表将存储多个值,如下所示:
def findNumber(self, nums):
values = []
for i in nums:
val = nums.count(i)
if val == 1:
values.append(i)
return values
答案 6 :(得分:1)
假设一个已排序的可迭代(否则对其进行排序),这是第一次出现非重复对:
import more_itertools as mit
iterable = [0, 0, 1, 1, 2, 2, 6, 6, 9, 10, 10]
next(x for x, y in mit.windowed(iterable, n=2, step=2) if x != y)
# 9
创建非重叠对的另一种方法:
next(x for x, y in mit.sliced(iterable, 2) if x != y)
# 9
more_itertools
是第三方库> pip install more_itertools
。
答案 7 :(得分:1)
在Python中执行此操作的一种好方法是使用collections.Counter来解决O(n)的复杂性:
from collections import Counter
def solution(A):
for x, occ in Counter(A).items():
if occ % 2:
return x
这还将泛化为返回数组中出现奇数次的任何数字。
答案 8 :(得分:0)
对于使用NumPy的任何人来说,这应该与其他答案在速度上具有竞争力:
>>> def get_single_instance_np(arr: np.ndarray):
... return np.asscalar(arr[np.bincount(arr) == 1])
>>> print(get_single_instance(a))
9
这只返回计数等于1的元素。
答案 9 :(得分:0)
{'host': 'host1',
'user': 'firsts_user',
'time': '01/01'}
def solution(A):
# write your code in Python 3.6
result =0
for i in A:
result ^= i
return result
时间复杂度: from itertools import groupby
def solution(A):
# write your code in Python 3.6
for key, group_list in groupby(sorted(A)):
if len(list(group_list)) % 2 == 1:
return key