找出数组中重复的数字
题目一:在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但是不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7,的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数组2或者3。(n个元素,n种可能的取值)
解法一:先对数组进行排序,然后再查找排序后的数组中的重复元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | def selectedSort(lis): for i in range(0, len(lis)): minVal = lis[i] minInd = i #找出最小的元素 for j in range(i+1,len(lis)): if minVal>=lis[j]: minVal=lis[j] minInd=j #交换 lis[minInd]=lis[i] lis[i]=minVal return lis lis=[8,5,3,3,7,6,3,9,1,8] lis_order=selectedSort(lis) print(lis) |
解法二:开辟一个新数组B,每次扫描源数组A中的元素,如果不在B中,就加入B中,如果在B中,就找到一个重复的元素
1 2 3 4 5 6 7 8 9 10 11 | lisA=[8,5,3,3,7,6,3,9,1,8] def findDuplicates(lisA): lisB = [] for i in lisA: if i in lisB: print( "找到一个重复的元素:%d" %i) break else : #当前扫描的元素不在lisB中,就加入到lisB中 lisB.append(i) continue findDuplicates(lisA) |
解法三:因为列表总共有n个元素,所有元素可能取到的元素有0~n-1,共n种。如果不存在重复的数字,那么排序后数字i将会出现在下标为i的位置。现在让我们重新扫描数组,
- 当扫描到下标为i的数字时,首先比较这个数字(记为m)与i是否相等:
- 如果是,继续扫描下一个元素,
- 如果不是,则再拿它与第m个数字比较:
- 如果它和第m个数字相同,就找到了一个重复的元素;
- 如果不同,就将m与第m个数字互换。接下来继续重头开始,重复换这个比较。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | lisA=[8,0,2,3,7,6,4,2,1,5] def findDuplicates(lisA): i=0 while i <len(lisA) and lisA!=[]: m = lisA[i] if m == i: i += 1 else : if m == lisA[m]: print( '找到一个重复的元素:%d' % m) break else : temp = lisA[i] lisA[i] = lisA[m] lisA[m] = temp i = 0 findDuplicates(lisA) |
题目二:
在一个长度为n+1的数组里的所有数字都在1~n范围内,所以数字中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但是不能修改数组。例如,如果输入长度为8的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或3。(n+1个元素,n种可能的取值)
解法一:同上题解法二,开辟一个大小为n+1的新数组
解法二:避免使用O(n)的辅助空间。我们把取值空间[1,n]从中间的数字m分为两部分,前面一部分为1~m,后面一部分为m+1~n。如果数组中元素落在前面一部分的元素个数多于m个,那么数组中重复的元素一定落在前半区间;否则,数组中重复的元素一定落在后半区间。然后,我们可以继续将包含重复元素的区间一分为二,直到找到一个重复的元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | lisA=[8,1,2,3,7,6,7,4,9,5,10] def findDuplicates(lisA): "" "找到重复元素,返回True;否则,返回False" "" low=1 high=len(lisA)-1 while low<=high: mid=(low+high) //2 #统计数组中落在前半部分区间中的元素的个数 count_low=0 for i in lisA: if i in range(low,mid+1): count_low+=1 #判断落在长度为1的区间中的数组元素个数 if high==low: if count_low>1: #如果大于1,则找到重复的元素 return low else : break #比较前半部分区间长度与落在该区间内元素的个数,决定将前半部分/后半部分区间继续一分为二 if count_low>(mid-low+1): high=mid else : low=mid+1 return False print(findDuplicates(lisA)) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
2018-07-16 Spark认识&环境搭建&运行第一个Spark程序
2018-07-16 Github使用之git回退到某个历史版本