题目描述

在一个长度为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
dic={}
for i in numbers:
if i in dic:
duplication[0]=i
return True
else: dic[i]=1
return False

  时间复杂度o(n),空间复杂度o(n)

然后想到用数组代替字典,因为数组内所有数字都在0到n-1的范围内,那么我可以创建一个大小为n的数组a,初始值都为0,利用数组下标记录a[i]是否为0。如果a[i]==0,那么说明该数字是第一次遍历到,令a[i]=1;如果a[i]==1,那么说明该数字是第二次遍历到,该数字重复,令duplication[0]=i,返回True;如果遍历完全后没有return False,那么就return True。

# -*- coding:utf-8 -*-
class Solution:
# 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
# 函数返回True/False
def duplicate(self, numbers, duplication):
# write code here
if len(numbers)==0: return False
a=[0]*len(numbers)
for i in numbers:
if not a[i]: a[i]=1
else:
duplication[0]=i
return True
return False

  时间复杂度o(n),空间复杂度o(n)

然后我觉得以上两种方法,空间复杂度都为o(n),应该还有空间复杂度更小的解法。但我想不出来了。

官方解法

也是利用数组下标的性质,但是不是新建一个数组,而是利用指针。i 从0的位置开始,一定要找到每个 i 对应的数字,即numbers[i]=i,才能继续下一个,如果交换过程中发现已经是numbers[i]=i,那么当前要交换的数字就是重复的数字。

 1 # -*- coding:utf-8 -*-
2 class Solution:
3 # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
4 # 函数返回True/False
5 def duplicate(self, numbers, duplication):
6 # write code here
7 if not numbers or len(numbers)==0:return False
8 for i in range(len(numbers)):
9 while i!=numbers[i]:
10 if numbers[i]==numbers[numbers[i]]:
11 duplication[0]=numbers[i]
12 return True
13 # swap
14 # numbers[i],numbers[numbers[i]] = numbers[numbers[i]],numbers[i]不可行
15 tmp=numbers[i]
16 numbers[i]=numbers[numbers[i]]
17 numbers[tmp]=tmp
18 return False

   时间复杂度o(n),空间复杂度o(1)

上述代码官方给的步骤:

    1. 设置一个指针i指向开头0,

    2. 对于arr[i]进行判断,如果arr[i] == i, 说明下标为i的数据正确的放在了该位置上,让i++

    3. 如果arr[i] != i, 说明没有正确放在位置上,那么我们就把arr[i]放在正确的位置上,也就是交换
      arr[i] 和arr[arr[i]]。交换之后,如果arr[i] != i, 继续交换。

    4. 如果交换的过程中,arr[i] == arr[arr[i]],说明遇到了重复值,返回即可。
      如下图:

                       
 

使用内置函数的解法

使用set函数可以删除无序数组中重复的数字。 https://www.runoob.com/python/python-func-set.html

使用 collections.Counter.most_common(1) 可以找到数组中重复最多的数字。https://blog.csdn.net/qwe1257/article/details/83272340

 1 # -*- coding:utf-8 -*-\
2 from collections import Counter
3 class Solution:
4 # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
5 # 函数返回True/False
6 def duplicate(self, numbers, duplication):
7 # write code here
8 if len(numbers)==0 or not numbers:return False
9 if len(numbers)==len(set(numbers)):return False
10 duplication[0]=Counter(numbers).most_common(1)[0][0]
11 return True
 
 
 
 

最新文章

  1. oracle11g重置system密码,外二
  2. python pycurl模块
  3. 用emacs的org2blog组件写cnblogs博客 -- 环境配置及使用
  4. CSS常用的属性命名
  5. JAVA设计模式--strategy(策略者模式)
  6. javascript代码复用--继承
  7. MVC 依赖注入/控制反转
  8. spring(四)之基于注解(Annotation-based)的配置.md
  9. jQuery 属性操作方法(五)
  10. Jstorm与RocketMQ整合
  11. 七、Android动画
  12. (链表) lintcode 219. Insert Node in Sorted Linked List
  13. 教你一个vue小技巧,一般人我不说的
  14. HDU 4612 Warm up 连通图缩点
  15. 在eclipse中导入hadoop jar包,和必要时导入源码包。
  16. mysql 2
  17. hdu1358 Period KMP
  18. Java课程作业之动手动脑(五)
  19. thinkphp if标签
  20. Vim自动补全插件----YouCompleteMe安装与配置

热门文章

  1. 第05组 Alpha冲刺 (2/6)(组长)
  2. 基于CSS3伪元素和动画绘制旋转太极图
  3. lseek系统调用
  4. struts.xml中的配置内容
  5. WinRM服务远程命令执行
  6. kali Linux的 安装详细步骤
  7. 用MathType怎么把分数打出来
  8. 14.java设计模式之命令模式
  9. 解决Jenkins可安装界面是空白的小技巧
  10. python基础之条件语句