算法演練一:數組中重複的數字

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

  • 1.當掃描到下標i的數字m[i],把i和m[i]做比較,若是相等,則掃描下一個,不然進入第二步。
  • 2.將m[i]和第m[i]個數字進行比較,若是相等,這就是一個重複的數字,掃描下一個數字。不然進入第三步。
  • 3.將m[i]和第m[i]進行交換,繼續僅從頭開始新的一輪掃描,直到結束。

上面的過程實質上就是比較交換的過程。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

相關文章
相關標籤/搜索