题目:长度为 n 的数组,里面所有数字都在 [0, n-1] 范围之内。数组中某些数字是重复的,但不知道有几个数字重复,也不知道每个数字重复几次。
要求:找出数组中任意一个重复的数字。
示例:输入 n = 7 的数组 {2, 3, 1, 0, 2, 5, 3},则输出 2 或 3。
思路:
- 哈希表。
- 遍历数组,将其中元素存入哈希表中,如果某个元素已经在哈希表中出现过,则其为重复数字。
- 缺点:使用额外存储空间。
- 变形的排序。
- 如果数组中无重复数字,则排序之后,numbers[i] = i,即数字 i 所在位置的下标也是 i,利用该特性对数组排序。排序过程中,如果某个位置的数字出现多个,该其为重复数字。
- 算法:
- 遍历数组,对于每个下标 i 的元素 numbers[i]:
- 判断 numbers[i] 是否等于 i:
- 如果 numbers[i] == i,表明该元素出于排序后的最终位置,处理下一个元素。
- 如果 numbers[i] != i,则交换下标 i 和 numbers[i] 两个位置上的元素,交换之后,numbers[i] 处于其最终位置上。
- 重复判断numbers[i] 是否等于 i,直到 numbers[i] == i。
- 判断 numbers[i] 是否等于 i:
- 遍历数组,对于每个下标 i 的元素 numbers[i]:
Java 实现:
public class Solution {
public boolean duplicate(int[] numbers, int length, int[] duplication) {
if (numbers == null || numbers.length <= 1)
return false;
for (int i = 0; i < numbers.length; i++) {
while (numbers[i] != i) { // 不断循环排序
if (numbers[i] == numbers[numbers[i]]) { // 发现重复数字
duplication[0] = numbers[i];
return true;
}
exch(numbers, i, numbers[i]);
}
}
return false;
}
private void exch(int[] n, int i, int j) {
int tmp = n[i];
n[i] = n[j];
n[j] = tmp;
}
}