LeetCode 剑指 Offer 03. 数组中重复的数字
题目链接:LeetCode 剑指 Offer 03. 数组中重复的数字
题意:
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
解题思路
1. 哈希
将数放入哈希表,如果当前哈希表已经有值,说明这个数重复了,(时间复杂度 O(n),空间复杂度O(n))
// 哈希
func findRepeatNumber(nums []int) int {
m := make(map[int]struct{})
for _, v := range nums {
if _, ok := m[v]; ok {
return v
}
m[v] = struct{}{}
}
return -1
}
2. 排序
先把数组排序,相同的肯定排在了一起,比较前后两个数是否相等(时间复杂度 O(nlogn))
// 排序,相同的排在了一起
func findRepeatNumber(nums []int) int {
sort.Ints(nums)
for i := 1; i < len(nums); i++ {
if nums[i] == nums[i-1] {
return nums[i]
}
}
return -1
}
3. 利用性质(最优解)
长度为 n 的数组 nums 里的数字都在范围 0 ~ n-1 内,尝试把当前的数归位到和下标一致,即让 nums[i] = i,所以有三个数:
- 当前下标 i
- 当前下标的值 nums[i]
- 当前下标的值应该被放的位置 nums[nums[i]]
(时间复杂度 O(n),空间复杂度O(1))
/* 利用性质,让 nums[i] 回到 i 位置
1. 比较 nums[i] 与 i 的关系,只有不等时才需要回归原位
2. 比较 nums[i] 与 nums[nums[i]]
[2, 3, 1, 0, 2, 5, 3]
1, 3, 2, 0, 2 5 3
3 1 2 0 2 5 3
0 1 2 3 2 5 3
0 1 2 3 2 2回不去了
*/
func findRepeatNumber(nums []int) int {
for i := range nums {
// i -> 0
// nums[0] -> 2
// nums[nums[0]] -> 1
for nums[i] != i {
// 本该回归的位置已经有数回归了,说明重复了
if nums[nums[i]] == nums[i] {
return nums[i]
}
nums[i], nums[nums[i]] = nums[nums[i]], nums[i]
}
}
return -1
}
YZ的代码:
```golang
func findRepeatNumber(nums []int) int {
n := len(nums)
for i,_ := range nums {
if nums[i] < 0 || nums[i] > n-1 {
return -1
}
}
for i,_ := range nums{
if nums[i] < 0 || nums[i] > n-1 {
return -1
}
for nums[i] != i && nums[nums[i]] != nums[i] {
nums[i],nums[nums[i]] = nums[nums[i]],nums[i]
}
if nums[i] != i && nums[nums[i]] == nums[i] {
return nums[i]
}
}
return -1
}

浙公网安备 33010602011771号