题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
# -*- coding:utf-8 -*-
class Solution:
# 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
# 函数返回True/False
def duplicate(self, numbers, duplication):
# write code here
if len(numbers)<=1:
return False
i=0
while i<=len(numbers):
m=numbers[i]
if m==i:
i+=1
else:
if numbers[i]==numbers[m]:
return True
else :
temp=numbers[i]
numbers[i]=numbers[m]
numbers[m]=temp
i+=1
return False
题目2:题目描述:
在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但是不能修改输入的数组。
def find_dux_num(seq):
if len(seq) <= 1 or seq is None:
return None
start, end = 1, len(seq) - 1 # 获取数字1,n
while start <= end:
mid = (start+end) // 2 # 获取中间数字
count = count_num(seq, start, mid) # 计算[start, mid]数字之间的数目
# 当只取到一个数字时,如果该数字出现数目大于1,就是重复数字
if start == end:
if count > 1:
return start
else:
break
# 如果count数目 > 中间数字到起始数字之差,一定存在重复数字,继续在这一段中求中间数比较
if count > mid - start + 1:
end = mid
# 否则在后一段中求中间数比较
else:
start = mid + 1
return None
def count_num(seq, start, end):
count = 0
for i in seq:
if start <= i <= end:
count += 1
return count
if __name__ == '__main__':
print(find_dux_num([1, 2, 3, 4, 3]))
作者:大白杏仁
链接:https://www.jianshu.com/p/b35c528e01d7
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
https://www.jianshu.com/p/b35c528e01d7 有详细的介绍
这种方法虽然不需要辅助空间O(n),但是后面每半个区间都需要遍历整个数组,函数countNum将被调用O(logn)次,每次需要O(n)的时间,因此总的时间复杂度是O(nlogn),空间复杂度为O(l)。相当于用时间换空间了。
现在来总结下关于数组中重复数字的问题,利用辅助空间的话,时间和空间复杂度都是O(n);利用下标于数字对应关系的话时间复杂度是O(n),空间复杂度是O(l),但是需要改变数组;利用二分查找类似思路的方法,时间复杂度是O(nlogn),空间复杂度O(l),所以要问清楚面试官他想要空间效率高的呢?还是时间效率高的呢?能不能改变数组呢?一方面体现交流能力,一方面能最快的写出答案。
还剩一个辅助空间法。