题目:在一个长度为n的数组里的全部数字都在0~n-1的范围内,找出对应重复的数字。例如输入长度为7的数组int[] m ={2,3,1,0,2,5,3},则重复的数字为2和3。java
解法一:使用快排,排序后再去作比较找重复的数字,这个方法的时间复杂度为O(nlogn),这是最多见的方法,可是不是最快的办法。数组
解法二:这里有个重点,就是n属于[0, n-1],也就是说若是没有重复的数字,那么下标i和m[i]是相等的,这个很好理解吧。那么让咱们重排数组,从头至尾扫描这个数组,过程以下:bash
上面的过程实质上就是比较交换的过程。ui
这里给出java版本的代码,以下:spa
public class Main {
static int[] a = {2, 3, 1, 0, 2, 5, 3};
public static void main(String[] args){
duplicate(a);
}
private static void duplicate(int[] numbers) {
if (numbers == null || numbers.length == 0) return;
for (int i = 0; i < numbers.length; i++){
while (numbers[i] != i){//第一步
if (numbers[i] == numbers[numbers[i]]){//第二步
System.out.println("重复的数字-----> " + numbers[i]);
break;
}
//第三步
int tmp = numbers[i];
numbers[i] = numbers[tmp];
numbers[tmp] = tmp;
}
}
}
}
复制代码
代码中尽管有两重循环,可是最多进行了2次交换就找到了它的位置,所以总的时间复杂度为O(n),全部的操做都在同一个数组上,没有额外的分配内存空间,空间复杂度为O(1);code