leetcode **41. 缺失的第一个正数(利用*(-1)和下标标记这个数已访问过)

【题目】**41. 缺失的第一个正数

给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。

示例 1:

输入: [1,2,0]
输出: 3

示例 2:

输入: [3,4,-1,1]
输出: 2

示例 3:

输入: [7,8,9,11,12]
输出: 1

提示:
你的算法的时间复杂度应为O(n),并且只能使用常数级别的额外空间。

【解题思路1】利用*(-1)和下标标记这个数已访问过

class Solution {
    public int firstMissingPositive(int[] nums) {
        int n = nums.length;
        //先将所有的负数变为 n+1
        for (int i = 0; i < n; ++i) {
            if (nums[i] <= 0) {
                nums[i] = n + 1;
            }
        }
        //加负号标记这个数已经被访问过了
        for (int i = 0; i < n; ++i) {
            int num = Math.abs(nums[i]);
            if (num <= n) {
                nums[num - 1] = -Math.abs(nums[num - 1]);
            }
        }
        //如果数组中还有正数,通过对应的下标找到最小缺失的数字
        for (int i = 0; i < n; ++i) {
            if (nums[i] > 0) {
                return i + 1;
            }
        }
        //0-n都存在的话
        return n + 1;
    }
}

【解题思路2】置换

将数放到对应下标的位置上,随后对应下标位置上的数不对那这就是要找的最小缺失数字

class Solution {
    public int firstMissingPositive(int[] nums) {
        int n = nums.length;
        for (int i = 0; i < n; ++i) {
            //一定要注意判断是否有重复数字,否则会进入死循环
            while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {
                int temp = nums[nums[i] - 1];
                nums[nums[i] - 1] = nums[i];
                nums[i] = temp;
            }
        }
        for (int i = 0; i < n; ++i) {
            if (nums[i] != i + 1) {
                return i + 1;
            }
        }
        return n + 1;
    }
}

你可能感兴趣的:(Leetcode,#,数组,#,重复数)