题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。
python实现:
# -*- coding:utf-8 -*-
class Solution:
# 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
# 函数返回True/False
def duplicate(self, numbers, duplication):
# write code here
n = len(numbers)
if n==0 or n==1:
duplication = numbers
return False
#找到一个重复值就行
#把数字放到它该在的位置
i = 0
while i<n:
if numbers[i]!=i:
if numbers[numbers[i]] == numbers[i]:
duplication[0] = numbers[i]
return True
tmp = numbers[i]############重要,
#直接写成numbers[i], numbers[numbers[i]] = numbers[numbers[i]], numbers[i]会出错,因为numbers[i]的值在改变
numbers[i], numbers[tmp] = numbers[tmp], numbers[i]
else:
i += 1
return False
扩展:其他条件同上,但上面的题目是找出任意一个重复的数字都行,现在题目改为找出第一个重复的数字:这就不能使用基于排序或交换的方法了,因为会改变数组中数字的顺序。
Python:
class Solution:
# 法1:hash表或者set
# 法2:双层循环 for i=0~n for j=i~n
# 法3:替换法
# 法1:hash或者set,时间复杂度O(n),空间复杂度O(n)
def duplicate2(self , numbers ):
# write code here
n = len(numbers)
if n<=1:
return -1
_set = set()
for i in range(n):
if numbers[i] not in _set:
_set.add(numbers[i])
else:
return numbers[i]
return -1
# 法2:双层循环 for i=0~n for j=i~n
# 时间复杂度O(n^2)
def duplicate(self , numbers ):
n = len(numbers)
if n<=1:
return -1
for i in range(n):
for j in range(i+1, n):
if numbers[j]==numbers[i]:
return numbers[i]
return -1
# 替换法:时间复杂度O(n)
def duplicate(self , numbers ):
# write code here
if not numbers:
return -1
n = len(numbers)
for i in range(n):
v = numbers[i]
if v < 0: # 还原数组中的值v
v += n
if numbers[v] < 0: # 说明v已经出现过了
return v
numbers[v] -= n # 标记
return -1