给定一个整数数组 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 }