給定一個整數數組 a,其中1 ≤ a[i] ≤ n (n爲數組長度), 其中有些元素出現兩次而其餘元素出現一次。數組
找到全部出現兩次的元素。app
你能夠不用到任何額外空間並在O(n)時間複雜度內解決這個問題嗎?code
示例:blog
輸入: [4,3,2,7,8,2,3,1] 輸出: [2,3]
遍歷給定數組時,能夠查看該元素是否存在於哈希表中,若不存在,則將該元素存到哈希表中,反之則是重複的元素。索引
但這個方法用到了額外空間,因此看看就好咯。
時間複雜度:O(n),空間複雜度:O(n)hash
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 }
由於題目說了,數組裏的全部數字都在 1 ~ n 的範圍內(n是數組長度),但數組的下標是從 0 開始,因此能夠遍歷數組,使數組的索引和值創建對應的關係,也就是索引爲 0 時,值爲 1,索引爲 1 時,值爲 2,以此類推。class
遍歷元素時,遍歷
當 a[i] != i+1 時,就將位置 i 和 a[i]-1 上的兩個值交換,反之則 i 移動到下一位。map
當 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 }