leetcode problem - 41. First Missing Positive

Title:

Given an unsorted integer array, find the first missing positive integer.

For example,
Given [1,2,0] return 3,
and [3,4,-1,1] return 2.

Your algorithm should run in O(n) time and uses constant space.

This problem is to find the first lost positive number. In the process of solving the problem, we mainly encounter the following special boundary conditions:

[1],
[2],
[-1,1],
[-1,1000],
[-1,1,1,1,2,22]

There may be great differences between the two numbers, or there may be duplicate numbers. The first reaction I saw was to sort the questions so that it would be easy to find the missing positive numbers. But in the middle, we met with these boundary conditions, which made us skip several times. Actually, all we need to do after sorting is to traverse the array and find numbers larger than zero and larger than one of the previous positive numbers. Code in:

    public int firstMissingPositive(int[] nums) {
        if(nums.length == 0 || nums == null)
            return 1;
        Arrays.sort(nums);
        for(int i=0; i<nums.length; i++){
            if(nums[i] > 0)
                if(nums[i] != 1)
                    return 1;
                else{
                    //Judge whether it is a mutation point and exclude the same situation
                    while(i < nums.length-1 && (nums[i+1] == nums[i]+1 || nums[i+1] == nums[i]))
                        i++;
                    return nums[i]+1;
                }
        }
        return nums[nums.length-1]+1;
    }

At the same time, there is another solution in my mind. That is to use an array to save the positive number that has been traversed. So there is a problem, such as [-1,1000] in this case, the number we applied for is not big enough. Later on, if this happens, it means that the lost number must be before that. That is to say, the original size of the array is enough to support, but we need to add a restriction, when an element is larger than the length of the array, do not save it in the array. Code in:

    public int firstMissingPositive1(int[] nums) {
        int n = nums.length;
        //This array is used to record the information of the original array, and the value of the original array is marked below.
        int[] tmp = new int[n+2];

        for(int i=0; i<n; i++){
            if(nums[i] > 0 && nums[i] < n+2){
                tmp[nums[i]] = 1;
            }
        }
        for(int i=1; i<n+2; i++)
            if(tmp[i] != 1)
                return i;

        return 1;
    }

But the title requires that we use constant storage space. So we should use the internal exchange of arrays to achieve, code into the following:

    public int firstMissingPositive2(int[] A) {
        int i = 0;
        while(i < A.length){
            if(A[i] == i+1 || A[i] <= 0 || A[i] > A.length) i++;
            else if(A[A[i]-1] != A[i]) swap(A, i, A[i]-1);
            else i++;
        }
        i = 0;
        while(i < A.length && A[i] == i+1) i++;
        return i+1;
    }

    private void swap(int[] A, int i, int j){
        int temp = A[i];
        A[i] = A[j];
        A[j] = temp;
    }

Posted by white99 on Mon, 11 Feb 2019 06:36:17 -0800