题目描述
在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。
也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为 7 的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字 2。
思路分析
对于这种数组元素在 [0, n-1] 范围内的问题,可以将值为 i 的元素调整到第 i 个位置上进行求解。也就是归位,当某个数发现自己的"位置"被相同的数占了,则出现重复。
1)扫描整个数组,当扫描到下标为 i 的数字时,首先比较该数字(m)是否等于 i,如果是,则接着扫描下一个数字;
2)如果不是,则拿 m 与第 m 个数比较。
3)如果 m 与第 m 个数相等,则说明出现重复了;如果 m 与第 m 个数不相等,则将 m 与第 m 个数交换,将 m "归位",再重复比较交换的过程,直到发现重复的数
以 (2, 3, 1, 0, 2, 5) 为例,遍历到位置 4 时,该位置上的数为 2,但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复:
最终时间复杂度 O(N),空间复杂度 O(1)。
解释说明:
public boolean duplicate(int[] numbers, int length, int[] duplication) {
if (numbers== null || length <= 0)//判空处理
return false;
for (int i = 0; i < length; i++) {
while (numbers[i] != i) { //是否众神归位
if (numbers[i] == numbers[numbers[i]]) {//是否位置被人占了
duplication[0] = numbers[i];
return true;
}
swap(numbers, i, numbers[i]);//交换归位
}
}
return false;
}
private void swap(int[] numbers, int i, int j) {
int t = numbers[i];
numbers[i] = numbers[j];
numbers[j] = t;
}
https://www.nowcoder.com/questionTerminal/623a5ac0ea5b4e5f95552655361ae0a8?answerType=1&f=discussion
来源:牛客网