#442-Find All Duplicates in an Array-陣列中重複的數字

鹿呦呦發表於2020-05-25

一、題目

給定一個整數陣列 a,其中1 ≤ a[i] ≤ n (n為陣列長度), 其中有些元素出現兩次而其他元素出現一次。

找到所有出現兩次的元素。

你可以不用到任何額外空間並在O(n)時間複雜度內解決這個問題嗎?

示例:

輸入:
[4,3,2,7,8,2,3,1]

輸出:
[2,3]

二、題解

  • 解法1:雜湊表

遍歷給定陣列時,可以檢視該元素是否存在於雜湊表中,若不存在,則將該元素存到雜湊表中,反之則是重複的元素。

但這個方法用到了額外空間,所以看看就好咯。
時間複雜度:O(n),空間複雜度:O(n)

func findDuplicates(nums []int) []int {
    len := len(nums);
    if len <= 1 {
        return nil
    }
    hashMap := make(map[int]int)
    result := []int{}
    for _, v := range nums {
        _, exist := hashMap[v];
        if (exist) {
            result = append(result, v)
        } else {
            hashMap[v] = v
        }
    }
    return result
}
  • 解法2:交換法——原地雜湊

因為題目說了,陣列裡的所有數字都在 1 ~ n 的範圍內(n是陣列長度),但陣列的下標是從 0 開始,所以可以遍歷陣列,使陣列的索引和值建立對應的關係,也就是索引為 0 時,值為 1,索引為 1 時,值為 2,以此類推。

遍歷元素時,

當 a[i] != i+1 時,就將位置 i 和 a[i]-1 上的兩個值交換,反之則 i 移動到下一位。

當 a[i] == a[a[i]-1]時,表示 a[i] 有重複,記錄重複數字,並把下標 i 上的數字置為 0。

當 i 上的數字是 0 時,i++

遍歷到陣列末尾,結束?

時間複雜度:O(n),空間複雜度:O(1)

func findDuplicates(nums []int) []int {
    len := len(nums)
    if len <= 1 {
        return nil
    }
    result := []int{}
    i := 0
    for i < len {
        if i == nums[i] - 1 || nums[i] == 0{
            i++
            continue
        }
        if nums[i] == nums[nums[i] - 1] {
            result = append(result, nums[i])
            nums[i] = 0
            i++
        } else {
            nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i] 
        }    
    }
    sort.Ints(result)
    return result
}

相關文章