- 落单的数
给出 2 * n + 1个数字,除其中一个数字之外其他每个数字均出现两次,找到这个数字。
样例
样例 1:
输入:[1,1,2,2,3,4,4]
输出:3
解释:
仅3出现一次
这个解法思路比较简单,遍历list A,把里面的元素取出来放到一个字典(哈希表)里。如果字典里没有该元素,就将其值置为1,如果该字典里已有该元素,就讲该key删除,这个没啥问题。
def singleNumber(self, A):
# write your code here
size = len(A)
if size == 1:
return A[0]
count_array = {}
for number in A:
if number in count_array:
del count_array[number]
else:
count_array[number] = 1
return count_array.keys()[0]
这个方法毕竟增加了空间成本,我们如果直接在list A上删除重复的元素,可不可以呢?思路是遍历list A中的每一个元素,连续删除2次。如果第二次删除不成功则会跑出ValueError错误,此时我们捕捉此异常应该就可以了。这里我们使用的list删除操作为remove()。因为其参数就是我们要找到元素,不是位置啥其他的东西。
def singleNumber(self, A):
# write your code here
size = len(A)
if size == 1:
return A[0]
for number in A:
try:
A.remove(number)
A.remove(number)
except ValueError:
return number
但却被现实抽了一记响亮的大嘴巴子。样例1的返回的答案是None。并不符合我们的预期。
为了让问题浮出水面,我们打乱样例的输入顺序,增加打印代码后重新测试。
X = [1,2,1,4,3,2,4]
def singleNumber(A):
# write your code here
size = len(A)
if size == 1:
return A[0]
index = 0
for number in A:
print ("number = %d" %number)
print ("index = %d" %index)
print (A)
try:
A.remove(number)
A.remove(number)
index+=1
except ValueError:
return number
结果为:
number = 1
index = 0
[1, 2, 1, 4, 3, 2, 4] A[0]=1
number = 4
index = 1
[2, 4, 3, 2, 4] A[1]=4
number = 2
index = 2
[2, 3, 2] A[2]=2 已经循环结束了,函数未return
None 所以结果为None
原因分析:
1.for number in list:中的number是按照下标走的。每次循环后都会增长一位。
2.list进行remove操作后原有元素位置发生变化。
3.上述两个原因造成该题这种方法完全不可控。
结论:对于序列类的数据结构操作,在对列表的元素遍历操作的时候,尽量避免对列表中的元素增删操作,除非你能控制住,比如只在序列的头删除,尾部增加数据。