​转载本文章请标明作者​​《爱喝纯净水的南荣牧歌》​

剑指offer | 面试题3:数组中重复的数字_数据结构

开始行动,你已经成功一半了,献给正在奋斗的我们


题目

找出数组中重复的数字。

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字;

  • 示例1
    输入:
    [2, 3, 1, 0, 2, 5, 3]
    输出:2 或 3

解题分析

如果这道题真的在面试中被问到了,一定要问面试官一个问题,对空间复杂度有没有要求,能不能修改原来的结构;

如果面试官说不可以修改数据结构的话,并且空间复杂度可以为O(n)的话,那么这里就要使用哈希表了;

  • 遍历整个数组,查看该元素在哈希表中(java中使用HashSet,Python中使用set())有没有该元素,有的话直接返回,没有的话将这个元素放到哈希表中;

但是题目中指定了一个条件,所有数字都在 0~n-1 的范围内,所以我猜面试官应该是想要一种可以修改原数据结构并且空间复杂度可以为O(n)的算法,下标定位算法;

  • 我们遍历这个数组,假设当前元素的索引是m,索引所在的元素的值是n,那么我们就要判断m和n是否相等,如果不相等的话,我们就要找到索引为n所在的元素,如果人家索引为n的值本来就是n我们就定为到了重复的数字,返回即可,如果索引为n的值不为n是x,那么我们就把索引n的值置为n,再把元素x放到索引x所在的位置上去;

代码

ps:这里笔者使用的python3.7


  • 哈希表
    ​class Solution: def findRepeatNumber(self, nums: List[int]) -> int: if nums is None or len(nums) == 0: return -1 nums_set = set() for num in nums: if num in nums_set: return num else: nums_set.add(num) ​
  • 下标定位法
    ​class Solution: def findRepeatNumber(self, nums: List[int]) -> int: if nums is None or len(nums) == 0: return -1 for i in range(len(nums)): if nums[i] != i and nums[nums[i]] == nums[i]: return nums[i] elif nums[i] != i and nums[nums[i]] != nums[i]: nums[nums[nums[i]]] = nums[nums[i]] nums[nums[i]] = nums[i] ​

剑指offer | 面试题3:数组中重复的数字_数据结构_02