必备知识

C+±–库函数swap的用法

由于题目要求我们「只能使用常数级别的空间」,而要找的数一定在 [1, N + 1] 左闭右闭(这里 N 是数组的长度)这个区间里。因此,我们可以就把原始的数组当做哈希表来使用。事实上,哈希表其实本身也是一个数组;
我们要找的数就在 [1, N + 1] 里,最后 N + 1 这个元素我们不用找。因为在前面的 N 个元素都找不到的情况下,我们才返回 N + 1;
那么,我们可以采取这样的思路:就把 1 这个数放到下标为 0 的位置, 2 这个数放到下标为 1 的位置,按照这种思路整理一遍数组。然后我们再遍历一次数组,第 1 个遇到的它的值不等于下标的那个数,就是我们要找的缺失的第一个正数。
这个思想就相当于我们自己编写哈希函数,这个哈希函数的规则特别简单,那就是数值为 i 的数映射到下标为 i - 1 的位置。

LeetCode---41. 缺失的第一个正数(将数组视为哈希表,把每个元素都放在其应该在的位置上)_算法

示例代码

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int len=nums.size();
        //我们要找的数就在 [1, N + 1] 里,最后 N + 1 这个元素我们不用找。
        //因为在前面的 N 个元素都找不到的情况下,我们才返回 N + 1;
        //就把 1 这个数放到下标为 0 的位置, 2 这个数放到下标为 1 的位置
        //按照这种思路整理一遍数组。(通过交换的方式进行放置,否则会覆盖掉一些元素)
        for(int i=0;i<len;i++){
            //while 循环不会每一次都把数组里面的所有元素都看一遍。如果有一些元素在这一次的循环中被交换到了它们应该在的位置,那么在后续的遍历中,
            //由于它们已经在正确的位置上了,代码再执行到它们的时候,就会被跳过。
            while(nums[i]!=i+1){
                //这里不直接进行返回是因为只有到最后才能知道结果
                //nums[i] == nums[nums[i] - 1]防止出现死循环
                if(nums[i]<=0||nums[i]>len||nums[i] == nums[nums[i] - 1]){
                    break;
                }
                //他要放的实际位置,将nums[i] 放置到对应位置上[1,2,3...]
                //进行交换操作
                swap(nums[i],nums[nums[i]-1]);
            }
        }

        for(int i=0;i<len;i++){
            if(nums[i]!=i+1){
                return i+1;
            }
        }
        return len+1;        
    }
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.

效果展示

LeetCode---41. 缺失的第一个正数(将数组视为哈希表,把每个元素都放在其应该在的位置上)_数组_02

相似题目

 442. 数组中重复的数据 448. 找到所有数组中消失的数字