NOTE
找到所有数组中消失的数字
找到所有数组中消失的数字 的 LeetCode 解题笔记。
这是历史学习笔记,可能存在过时或不完整的理解。
1. 题目描述
给定一个范围在 1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。
找到所有在 [1, n] 范围之间没有出现在数组中的数字。
您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。
2. 思路
- 思路一
- 遍历一遍装入set
- 再查看[1, n]是否再set中
- 思路二
- 由于数字范围均在 [1,n][1,n] 中,我们也可以用一个长度为 nn 的数组来代替哈希表
3. 实现
3.1. HashMap
//空间复杂度:O(N)
//时间复杂度:O(N)
func findDisappearedNumbers(nums []int) []int {
res := make([]int, 0)
count := make(map[int]bool, 0)
for _, num := range nums {
count[num] = true
}
for i := 1; i <= len(nums); i++ {
if !count[i] {
res = append(res, i)
}
}
return res
}
- 或者直接用数组
func findDisappearedNumbers(nums []int) []int {
count := make([]byte, len(nums))
for _, val := range nums {
count[val-1] = 1
}
res := make([]int, 0)
for index, val := range count {
if val != 1 {
res = append(res, index+1)
}
}
return res
}
3.2. 原地hash
//空间复杂度:O(1)
//时间复杂度:O(N)
func findDisappearedNumbers2(nums []int) []int {
n := len(nums)
//对于每个val,将其作为index(即val-1),把index位置上的数都加上len
for _, v := range nums {
v = (v - 1) % n
nums[v] += n
}
//如果一个数<=len,说明了这个index上的额数没有加上len,也就是说val(即index+1)不存在
res := make([]int, 0)
for i, v := range nums {
if v <= n {
res = append(res, i+1)
}
}
return res
}
func findDisappearedNumbers(nums []int) []int {
for i := range nums {
for {
index := indexFor(nums[i])
if index < 0 || index > len(nums)-1 {
break
}
if nums[i] == nums[index] {
break
}
nums[index], nums[i] = nums[i], nums[index]
}
}
var res []int
for i := range nums {
index := indexFor(nums[i])
if index != i {
res = append(res, i+1)
}
}
return res
}
func indexFor(val int) int {
return val-1
}
讨论
使用 GitHub 账号参与讨论,评论会保存在 GitHub Issues 中。在 GitHub 查看