剑指offer:
面试题03:数组中重复的数字
题目:
在一个长度为n的数组中的所有数字都在 0~n-1 的范围内,数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
解法一:排序
解决此问题的一个简单方法就是先将此数组排序,再进行遍历,相邻数字相同即找到。排序一个数组的时间复杂度为O(nlogn)
步骤:
- 将数组排序
- 遍历数组寻找重复值
解法二:哈希表
寻找重复值,很明显可以利用哈希表中元素的不可重复性来实现:
遍历数组,判断是否存在于哈希表中,若不存在则添加至哈希表中,若存在,则找到该重复数字。
步骤:
- 遍历数组
- 判断是否存在于哈希表,不存在,添加至哈希表,存在,得到题解
解法三:
题目中给出的数组中的数字是在0~n-1范围内,故如果此数组没有重复数字,那么排序后,数字和其所在的下标是相等的。若此数组存在重复的数字,则至少有两个数字对应一个下标。
则:我们从头开始遍历数组(未排序)。当扫描到下标为i
的数字时,首先判断这个数字(nums[i]
)是否等于i
,若等于,则继续遍历下一个数字,若这个数字与i
不相等,则继续判断nums[i]
是否等于下标为nums[i]
的数字,若相等,则重复了,直接返回,若不相等,则交换它们的值,重复上述比较,直到找到题解。
步骤:
- 遍历数组
- 比较
nums[i]
是否等于i
- 若等于,遍历下个数;
- 否则继续判断
nums[i]
是否等于下标为nums[i]
的数- 相等,重复了,解题完毕,返回
- 不相等,交换它们的值,返回第二步继续比较
Java示例:
public int findRepeatNumber(int[] nums) {
for (int i = 0; i < nums.length; i++) {
while (nums[i] != i){
if (nums[i] == nums[nums[i]]){
return nums[i];
}
int temp = nums[i];
nums[i] = nums[nums[i]];
nums[temp]= temp;
}
}
return -1;
}