劍指offer(一):找出數組中重複的數字

❝
涓滴之水終能夠磨損大石,不是因爲它力量強大,而是因爲晝夜不捨的滴墜。——貝多芬

❞

找出數組中重複的數字


題目描述

在一個長度爲 n 的數組裏的全部數字都在 0 到 n-1 的範圍內。數組中某些數字是重複的,但不知道有幾個數字重複了,也不知道每一個數字重複了幾回。請找出數組中任意一個重複的數字。例如,若是輸入長度爲 7 的數組 {2, 3, 1, 0, 2, 5, 3},那麼對應的輸出是重複的數字 2 或者 3。git

解法

解法一
排序後,順序掃描,判斷是否有重複,時間複雜度爲 O(n²)。github

解法二
利用哈希表,遍歷數組,若是哈希表中沒有該元素,則存入哈希表中,不然返回重複的元素。時間複雜度爲 O(n),空間複雜度爲 O(n)。算法

解法三
長度爲 n,元素的數值範圍也爲 n,若是沒有重複元素,那麼數組每一個下標對應的值與下標相等。數組

從頭至尾遍歷數組,當掃描到下標 i 的數字 nums[i]:ide

  • 若是等於 i,繼續向下掃描;
  • 若是不等於 i,拿它與第 nums[i] 個數進行比較,若是相等,說明有重複值,返回 nums[i]。若是不相等,就把第 i 個數 和第 nums[i] 個數交換。重複這個比較交換的過程。
    此算法時間複雜度爲 O(n),由於每一個元素最多隻要兩次交換,就能肯定位置。空間複雜度爲 O(1)。
/**
 * @author bingo
 * @since 2018/10/27
 */

public class Solution {
    /**
     * 查找數組中的重複元素
     * @param numbers 數組
     * @param length 數組長度
     * @param duplication duplication[0]存儲重複元素
     * @return boolean
     */
    public boolean duplicate(int[] numbers, int length, int[] duplication) {
        if (numbers == null || length < 1) {
            return false;
        }
        for (int e : numbers) {
            if (e >= length) {
                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;
    }
}

測試用例

  1. 長度爲 n 的數組中包含一個或多個重複的數字;
  2. 數組中不包含重複的數字;
  3. 無效測試輸入用例(輸入空指針;長度爲 n 的數組中包含 0~n-以外的數字)。

我把我寫的全部題解整理成了一本電子書放在了 github 上,三天內衝擊到 github 排行榜榜首!近 5w 人下載閱讀!要獲取的話,直接進入下方連接就能夠了(記得給我點個 star):測試

https://github.com/geekxh/hello-algorithm指針

劍指offer(一):找出數組中重複的數字

相關文章
相關標籤/搜索