题目

题目地址:https://www.nowcoder.com/practice/623a5ac0ea5b4e5f95552655361ae0a8?tpId=13&tqId=11203&tPage=3&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking

题目描述:

在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为 7 的数组 {2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字 2。

相关题目:

思路

第一个想法

  • 循环遍历,使用哈希表来存储结果:时间和空间复杂度都是 O(n)


好的方法

一种空间复杂度为 O(1) 的办法
用下表来进行说明:第一行(index) 是数组的索引值,由于题目说数值的范围在 0-(n-1) 区间,那么,我们使用排序这个数组,规则是这样的:

  • 遍历整个数组,判读当前的索引值与在索引值位置的数是否相等
  • 如原始数组是 [2, 3, 1, 0, 2, 5, 3],index=0 的值是 2,它与索引值 index=0 不相等,所以就将 index=0 的值 2 与 index=2 的值 1 进行交换,得到第三行
  • 此时 index=0 的值是 1,它与索引值 index=0 不相等,所以将 index=0 的值 1 与 index=1 的值 3 进行交换,得到第四行
  • 此时 index=0 的值是 3,它与索引值 index=0 不相等,所以将 index=0 的值 3 与 index=3 的值 0 进行交换,得到第五行
  • 此时 index=0 的值 是 0;index=1 的值是 1;index=2的值是 2;index=3 的值是 3;index=4 的值是 2 不符合条件,所以判读与 index=2 的值是否相等,相等的话就证明 2 就是重复的数字
index 0 1 2 3 4 5 6
原始数组 2 3 1 0 2 5 3
第三行 1 3 2 0 2 5 3
第四行 3 1 2 0 2 5 3
第五行 0 1 2 3 2 5 3
第六行 0 1 2 3 2 5 3

image.png

代码

边界条件

  • 数组为空
  • 数组中数字必须在 0-(1-n) 的范围内
  1. # -*- coding:utf-8 -*-
  2. class Solution:
  3. # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
  4. # 函数返回True/False
  5. def duplicate(self, numbers, duplication):
  6. # write code here
  7. length = len(numbers)
  8. if length == 0 or not numbers:
  9. return False
  10. for num in numbers:
  11. if num > length-1 or num < 0:
  12. return False
  13. for i in range(length):
  14. while i != numbers[i]:
  15. if numbers[i] == numbers[numbers[i]]:
  16. duplication[0] = numbers[i]
  17. return True
  18. temp = numbers[i]
  19. numbers[i], numbers[temp] = numbers[temp], numbers[i]
  20. return False

OrderedDict 方法

  1. from collections import OrderedDict
  2. class Solution:
  3. def findRepeatNumber(self, nums: List[int]) -> int:
  4. d = OrderedDict()
  5. for num in nums:
  6. if num not in d:
  7. d[num] = 1
  8. else:
  9. d[num] += 1
  10. for k, v in d.items():
  11. if v > 1:
  12. return k
  13. """
  14. class Solution:
  15. def findRepeatNumber(self, nums: List[int]) -> int:
  16. d = {}
  17. for num in nums:
  18. if num not in d:
  19. d[num] = 1
  20. else:
  21. return num
  22. """

Set 集合方案

  1. class Solution:
  2. def findRepeatNumber(self, nums: List[int]) -> int:
  3. s = set()
  4. for num in nums:
  5. if num in s:
  6. return num
  7. else:
  8. s.add(num)