题目描述:
在一个长度为n的数组里的所有数字都在0~n-1的范围内,数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数字中任意一个重复的数字。例如,如果输入长度为7的数字{2, 3, 1, 0, 2, 5, 3},那么对应的输出是重复的数字2或者3
算法思想:
对于特殊的数组:长度为n的数组,所有数字都在0~n-1的范围内。
- 最简单的方法是对这个数组进行排序,然后对数组进行扫描,扫描数组的时间复杂度为O(n)
- 利用哈希表解决问题,从头到尾按照顺序扫描数组中的每一个元素,每次扫描一个元素用O(1)的时候判断哈希表中是否有这个元素。如果哈希表中没有,则把它加入哈希表;如果哈希表中已经有了,则找到重复元素
- 利用这个数组的特性进行重复元素的查找。如果这个数组中没有重复的元素,当数组排序之后,下标 i 的位置上是数字 i。我们在这里可以认为数字m出现在下标为i的位置上是数字m应该出现的位置。但是由于数组中存在重复的数字,因此有些下标为 i 位置出现的数字不是m
算法思想:
假定: 下标 i 数字m表示 数组Lst表示 - 对 下标 i 进行遍历,判断 i ?= m*
- if i == m 则继续遍历 i +=1
- if i != m 比较 m ?= Lst[m]
- if m == Lst[m] 则找到重复元素
- ##我们关心的是数字m看出现的次数。数字m第一次出现在下标 i 的位置上(下标i和数字m不等),第二次又出现在下标为m的位置上,m就是我们需要查找的重复数字。由于数组中存在重复数字,所以某些位置上的下标和位置上的数字对应的值是不同的,也就是第一次出现的下标为i的位置和位置上的元素不同,但是m == Lst[m],m出现在它应该出现的位置上。m为重复元素。
- if m != Lst[m] 则交换Lst[i]和Lst[m] 继续遍历 i +=1
- ##m数字只出现一次,在下标为 i 的位置上,下标和下标上的数字不对应。交换Lst[i]和Lst[m],又Lst[i] = m,这一步将数字m放到了它应该在的地方。 i += 1继续进行遍历
'''
Creat by HuangDandan
2018-08-18
解题思路:
思路1-直接对数组进行排序,排序方法可以任选,然后进行顺序遍历 时间复杂度和排序方法有关
思路2-顺序扫描数组,利用哈希表检查是否出现过:时间复杂度O(n),空间复杂度O(n)
思路3-顺序扫描数组,在数组相对应的位置i上看数字是否是i: Lst[i] == i
如果是,继续遍历下一个;
如果不是,计数值为m,比较j与m位置的数字:
如果相等,则返回重复数字
如果不相等,则交换i和m位置对应的数值,继续循环
'''
def mothod1(Lst):
#冒泡排序,排序后的列表temp
#i循环的次数
#j两两比较的次数
for i in range(len(Lst)-1):
for j in range(len(Lst)-i-1):
if Lst[j] > Lst[j+1]:
Lst[j],Lst[j+1] = Lst[j+1], Lst[j]
for k in range(0,len(Lst)-1):
if Lst[k+1] == Lst[k]:
return Lst[k]
import numpy as np
def mothod2(a):
num_array = np.zeros(len(a))
for i in range(len(a)):
if num_array[a[i]] == 0:
num_array[a[i]] += 1
else:
return a[i]
def mothod3(Lst): #返回一个重复的值
for index, value in enumerate(Lst):
while value != index:
if Lst[value] == value:
return value
else:
Lst[index], Lst[value] = Lst[value], Lst[index]
def mothod4(a): #返回一个重复的值
for i in range(len(a)):
while a[i] != i: #非常关键,当这个条件满足时,一直执行,直到不满足为止
if a[a[i]] == a[i]:
return a[i]
else:
a[a[i]], a[i] = a[i], a[a[i]] #目标是遍历交换使得a[a[i]] == a[i]成立,返回a[i],一定可以找到,所以不会是死循环
def mothod5(a): #返回多个重复的值,时间很慢
temp = []
for i in range(len(a)):
while a[i] != i: #非常关键,当这个条件满足时,一直执行,直到不满足为止
if a[a[i]] == a[i]:
temp.append(a[i])
else:
a[a[i]], a[i] = a[i], a[a[i]] #目标是遍历交换使得a[a[i]] == a[i]成立,返回a[i],一定可以找到,所以不会是死循环
return temp
if __name__ == "__main__":
Lst1 = [0,1,2,3,4,6,4]
Lst2 = [0,1,2,3,4,6,6]
Lst3 = [0,1,2,3,4,6,4,6]
Lst4 = [2,5,4,2,5,3]
Lst5 = [1, 0]
print(Lst1)
print("----------------------------------------")
# print(max(Lst1))
#print(mothod4(Lst1))
print(mothod2(Lst1))
#mothod3(Lst3)
# Lst2 = [None for i in range(10)]
# print(Lst2)
'''