数组

方法1:交换

public int firstMissingPositive(int[] nums) {
    int n = nums.length;
    for (int i = 0; i < n; i++) {
        //前两个条件是为了判断nums[i]是否在0-n范围内,防止index越界
        //后一个是判断i 这个index(当前的值)和nums[i]-1这个index(标准位置)是否相等,
        //标准位置:某个数nums[i] 落整个array的i-1的位置上
        while (nums[i] > 0 && nums[i] <= n && nums[i] != nums[nums[i] - 1]) {
            swap(nums, i, nums[i] - 1);
        }
    }
    //判断第一个出现异常的数字
    for (int i = 0; i < n; i++) {
        if (nums[i] - 1 != i) {
            return i + 1;
        }
    }
    return n + 1;
    //[3, 4, 4, -1, 1]->[1,4,3,4,-1] 异常的时index为1的数nums[1] 其值约为 (1+1=2)但是实际是4
    //[3, 4, -1, 1]  -->[1,-1,3,4]
    //[3,4,-1,-2,1,5,16,0,2,0]-->[1,2,3,4,5,-1,16,0,-2,0]
}

private void swap(int[] nums, int m, int n) {
    int temp = nums[m];
    nums[m] = nums[n];
    nums[n] = temp;
}

方法2:BitSet

  • 翻转方向和标记已经访问的点,是本题的关键

方法1:优先队列

方法2:快排

方法3:堆排序

方法1:Set

方法2:lambda

方法3:排序

方法1:标记

思路

我们也可以给nums[i] 加上「负号」表示数 i+1 已经出现过一次。具体地,我们首先对数组进行一次遍历。当遍历到位置 i 时,我们考虑 nums[nums[i]−1] 的正负性:

  • 如果 nums[nums[i]−1] 是正数,说明nums[i] 还没有出现过,我们将 nums[nums[i]−1]加上负号;

  • 如果 nums[nums[i]−1]是负数,说明 nums[i] 已经出现过一次,我们将 放入答案。

细节

  • 由于nums[i] 本身可能已经为负数,因此在将nums[i] 作为下标或者放入答案时,需要取绝对值。

方法2:交换

  • 将442题的方法2修改下

Last updated