41. 缺失的第一个正数

63 阅读1分钟

题目:

image.png

链接:leetcode.cn/problems/fi…

解题思路:【原地哈希】

  1. 不能对数组进行排序,排序的时间复杂度为O(nlogn)。
  2. 假设数组长度为N,则返回的数字一定在[1, N+1]中,因此,建立一个hash表,索引为i的位置存储值为i+1的值;在原数组建立hash表。
  3. 遍历完一次数组后,在遍历一次hash表,当不满足上述索引对应关系的索引应该填充的数就是返回值。

例子:
输入: [3,4,-1,1,0,2,2,3,6]
变化后的nums: [ 1, 2, 3, 4, 0, 6, 2, 3, -1 ]
执行过程: nums[i] = i+1

迭代过程数组变化前数组变化后
1[3,4,-1,1,0,2,2,3,6][-1,4,3,1,0,2,2,3,6]
2[-1,4,3,1,0,2,2,3,6][-1,1,3,4,0,2,2,3,6]
3[-1,1,3,4,0,2,2,3,6][-1,1,3,4,0,2,2,3,6]
4[-1,1,3,4,0,2,2,3,6][-1,1,3,4,0,2,2,3,6]
5[-1,1,3,4,0,2,2,3,6][-1,1,3,4,0,2,2,3,6]
6[-1,1,3,4,0,2,2,3,6][-1,2,3,4,0,1,2,3,6]
7[-1,2,3,4,0,1,2,3,6][-1,2,3,4,0,1,2,3,6]
8[-1,2,3,4,0,1,2,3,6][-1,2,3,4,0,1,2,3,6]
9[-1,2,3,4,0,1,2,3,6][-1,2,3,4,0,6,2,3,1]
10[-1,2,3,4,0,6,2,3,1][1,2,3,4,0,6,2,3,-1]

代码:

/**
 * @param {number[]} nums
 * @return {number}
 */
var firstMissingPositive = function(nums) {
  let len = nums.length
  for(let i=0; i<len; i++){
    // 根据索引和值的关系变化索引,返回的值一定在[1,N]之间
    // 满足条件
    // 在[1, N]范围内且没有放到正确的条件上
    while(nums[i]> 0 && nums[i] <= len && nums[i] != nums[nums[i]-1]){
      let t = nums[nums[i]-1]
      nums[nums[i]-1] = nums[i]
      nums[i] = t
    }
  }

  // 查找是否有不对应的关系
  for(let i =0; i< len; i++){
    if(nums[i] != i + 1){
      return i + 1
    }
  }
  return len + 1
};