題目:
在一個長度爲n的數組裏的所有數字都在 0~n-1的範圍內。數組中某些數字是重複的,但不知道有幾個數字是重複的,也不知道每個數字重複了幾次。請找出數組中任意一個重複的數字。例如:如果輸入長度爲7的數組{2,3,1,0,2,5,3},那麼對應的輸出的是重複的數字2或者3。
先說一下簡單的做法:
思路:
將數組排好序,再遍歷數組,找到數組中的重複數字即可。使用快排
package day05;
public class test1 {
//使用快排對數組進行排序
public void quicksort(int[] a, int left, int right) {
int i, j, temp, t;
if (left > right)
return;
i = left;
j = right;
temp = a[left];
while (i < j) {
while (temp <= a[j] && i < j) {
j--;
}
while (temp >= a[i] && i < j) {
i++;
}
if (i < j) {
t = a[j];
a[j] = a[i];
a[i] = t;
}
}
a[left] = a[i];
a[i] = temp;
quicksort(a, left, j - 1);
quicksort(a, j + 1, right);
}
public void change(int[] arr) {
//找到重複的數字並打印
for (int i = 0; i < arr.length; i++) {
int cur = arr[i];
int j;
for (j = i - 1; j >= 0; j--) {
if (arr[j] == arr[j+1]){
System.out.println(arr[j] + "");
}else
break;
}
}
}
public static void main(String[] args) {
test1 t = new test1();
int[] arr = {2, 3, 1, 0, 2, 5, 3,5};
t.quicksort(arr, 0, arr.length - 1);
t.change(arr);
}
}
上面的代碼有缺陷,因爲它打印的並不僅僅是重複的數字,而是數字重複幾次,就把數字打印幾次,比如出現3次2,就會打印2,2,2。
第二種是基於基數排序的一種做法
//因爲數字都是在0~n-1的n個數中,因此每一個數都有自己的槽位,即num[i] = num[num[i]] //要是不相等就交換,對於交換到i的數字還要進行比較,循環,直到每個數字到達自己的槽位 //要是數字有重複,就返回num[i]。 //需要注意的就是,數字必須在0~n-1之間
public int getNum(int[] arr) {
if (arr == null || arr.length <= 0) {
return -1;
}
for (int a : arr) {
if (a < 0 || a > arr.length - 1) {
return -1;
}
}
for (int i = 0; i < arr.length; i++) {
int temp;
while (arr[i] != i) {
if (arr[arr[i]] == arr[i])
return arr[i];
// 交換arr[arr[i]]和arr[i]
temp = arr[i];
arr[i] = arr[temp];
arr[temp] = temp;
}
}
return -1;
}
public void test() {
int[] a = { 1, 2, 3, 2, 4 };
int dup = getNum(a);
if (dup >= 0)
System.out.println("重複數字爲:" + dup);
}
}