题目:
集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。
给定一个数组 nums 代表了集合 S 发生错误后的结果。
请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
算法:
方法一:hash表 注意题目要求先返回重复的数,再返回丢失的数
func findErrorNums(nums []int) []int {
n := len(nums)
numMap := make(map[int]int)
for i := range nums {
numMap[nums[i]] ++
}
lost, repeat := 0, 0
for i := 1; i <= n; i ++ {
cnt, ok := numMap[i]
if !ok {
lost = i
}
if cnt > 1 {
repeat = i
}
}
return []int{repeat, lost}
}
方法二:循环
分类讨论,注意lost的条件是 nums[i] + 2 == nums[i + 1]
func findErrorNums(nums []int) []int {
n := len(nums)
sort.Ints(nums)
lost, repeat := 0, 0
if nums[0] != 1 {
lost = 1
}
if nums[n - 1] != n {
lost = n
}
for i := range nums {
if i + 1 < n {
if nums[i] == nums[i + 1] {
repeat = nums[i]
}
if nums[i] + 2 == nums[i + 1] {
lost = nums[i] + 1
}
}
}
return []int{repeat, lost}
}
方法三:桶排序
func findErrorNums(nums []int) []int {
n := len(nums)
for i := 0; i < n; i ++ {
// for循环直到nums[i] == i + 1或者nums[i] == nums[nums[i] - 1]
// 这里是对nums排序, for循环条件 nums[i] != nums[nums[i] - 1]) 避免左右相等时陷入死循环
for (nums[i] != i + 1 && nums[i] != nums[nums[i] - 1]) {
// fmt.Println(i, nums[i] - 1, nums )
nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i]
}
}
a, b := -1, -1
for i := 0; i < n; i++ {
if (nums[i] != i + 1) {
a = nums[i]
if i == 0 {
b = 1
} else {
b = nums[i - 1] + 1
}
}
}
return []int{a, b}
}