4.【442】数组中重复的数据
给你一个长度为 n 的整数数组 nums ,其中 nums 的所有整数都在范围 [1, n] 内,且每个整数出现 一次 或 两次 。请你找出所有出现 两次 的整数,并以数组形式返回。你必须设计并实现一个时间复杂度为 O(n) 且仅使用常量额外空间的算法解决此问题。
思路:
这题和448很像的。都是通过把当前的下标映射到nums[i]-1这个下标,通过把这个下标所对应的值置为负数,来说明当前第i个位置已经出现过。
1、从起始位置进行遍历,每次将下标为 nums[i]−1的数字取反;
2、当遍历到值 nums[i] 为负数,需要忽略其负号。
3、若发现下标为 nums[i]−1的数字已经是负数,说明之前出现过同样的数字 nums[i],即找到了重复数字;
func findDuplicates(nums []int) []int {
res := []int{}
for i, v := range nums {
if nums[abs(v)-1] < 0 { // 如果遇到负值,说明前面已经标记过一次,所以这是第二次
res = append(res, abs(nums[i])) // 把其值保存起来,别忘记这里nums[v-1]代表的是第i个下标的标记。所以返回nums[i]
}
nums[abs(v)-1] *= - 1 // 给下标nums[i]-1标记为负值
}
return res
}
func abs(a int) int {
if a < 0 {
return -a
}
return a
}