方法一:原地哈希

具体做法:

  • step 1:我们可以先遍历数组将所有的负数都修改成n+1。
  • step 2:然后再遍历数组,每当遇到一个元素绝对值不超过n时,则表示这个元素是1~n中出现的元素,我们可以将这个数值对应的下标里的元素改成负数,相当于每个出现过的正整数,我们把与它值相等的下标都指向一个负数,这就是类似哈希表的实现原理的操作。
  • step 3:最后遍历数组的时候碰到的第一个非负数,它的下标就是没有出现的第一个正整数,因为它在之前的过程中没有被修改,说明它这个下标对应的正整数没有出现过。

时间复杂度:o(n)

空间复杂度:o(1)

class Solution {
  public:
    int minNumberDisappeared(vector<int>& nums) {
        int size = nums.size();

        //负数置为size+1
        for (int i = 0; i < size; i++) {
            if (nums[i] < 0)
                nums[i] = size + 1;
        }
        //将数组中数字对应的下标数字置为负数
        for (int i = 0; i < size; i++) {
            if (abs(nums[i]) > 0 && abs(nums[i]) <= size)
                nums[abs(nums[i]) - 1] = -1 * nums[abs(nums[i]) - 1];
        }
        //依然是正数的下标就是没有出现的最小正整数
        for (int i = 0; i < size; i++) {
            if (nums[i] > 0)
                return i + 1;
        }
        //如果数组恰好时从1开始的递增序列,输出size
        return size + 1;
    }
};

方法二:排序

1、先对数组进行排序;

2、排序后的数组就很容易查找不存在的最小正整数。

时间复杂度:o(n)

空间复杂度:o(1)

class Solution {
  public:
    int minNumberDisappeared(vector<int>& nums) {
	  	//对数组进行排序
        sort(nums.begin(), nums.end());

        int temp = 1;
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] <= 0)
                continue;

            if (nums[i] == temp) {
                temp++;
                continue;
            } else {
                return temp;
                break;
            }
        }
        return temp;
    }
};