題目:在一個長度爲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