代码1:
- 因为要找的是最小正数,所以只需要考虑值在(1——n)之间的的数就可以了,如果有值大于n,或存在一个数为负数,那么说明一定有一个小于n的数不在数组中
- 所以我们只需要将数组中值在(1——n)之间的数当成下标,改变此下标的值,最后遍历一遍,看那个下标没有改变,那么那个下标所对应的值自然就是缺失的那个正数
- 但因为我们是在原数组中做的变化,我们必须保证在我们做完标记后,这个数字我们还可以还原出来,因为这个值我们可能还有用,所以我们可以将值变为负数来做为一种标记
- 如果以负数为标记,那么我们自然要将原数组中的负数变为一个大于 n 的正数,从而不让它影响我们
- 所以第一个for,将负数变为正数
- 第二个for,将(1——n)之间的值进行标记
- 第三个for,查找那个下标未被标记,因为标记对应的是(0——n-1)所以,return的时候应该下标加一
- 如果遍历完,都存在,那么返回 n+1
func firstMissingPositive(nums []int) int {
n := len(nums)
for i, v := range nums {
if v <= 0 {
nums[i] = n + 1
}
}
for _, v := range nums {
v = abs(v)
if v <= n {
nums[v-1] = -abs(nums[v-1])
}
}
for i, v := range nums {
if v > 0 {
return i + 1
}
}
return n + 1
}
func abs(n int) int {
if n < 0 {
return -n
}
return n
}
代码2:
置换:将(1——n)放到属于自己的位置
nums[nums[i]-1] != nums[i],防止一直和自己交换,死循环
func firstMissingPositive(nums []int) int {
n := len(nums)
for i := 0; i < n; i++ {
for nums[i] > 0 && nums[i] <= n && nums[nums[i]-1] != nums[i] {
nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1]
}
}
for i := 0; i < n; i++ {
if nums[i] != i + 1 {
return i + 1
}
}
return n + 1
}