LeetCode41. 缺失的第一个正数(java)

题目:

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

示例:
LeetCode41. 缺失的第一个正数(java)
说明:

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

代码:(Java)

  • 解法一
class Solution {
	public int firstMissingPositive(int[] nums) {
	//数组为空
		if (nums == null) {
			return 0;
		}
	//数组没有元素
		if (nums.length == 0) {
			return 1;
		}
	//数组长度为1时
		if (nums.length == 1) {
			if (nums[0] == 1) {
				return (nums[0] + 1);
			} else {
				return 1;
			}
		}
	//数组排序
		Arrays.sort(nums);
	//去除数组中的非正整数
		int[] newNums = new int[0];
		boolean flag = false;
		for (int i = 0; i < nums.length; i++) {
			if (nums[i] > 0) {
				flag = true;
				newNums = Arrays.copyOfRange(nums, i, nums.length);
				break;
			}
		}
		int newNumsLength = newNums.length;
		if (!flag) {
			return 1;
		}
	//去除重复的元素
		int index = 1;
		boolean flag1 = false;
		for (int i = 1, len = newNums.length; i < len; i++) {
			if (newNums[i] != newNums[i - 1]) {
				flag1 = true;
				newNums[index++] = newNums[i];
			}
		}
		if (flag1) {
			newNums = Arrays.copyOf(newNums, index);
		} else {
			newNums = Arrays.copyOf(newNums, newNumsLength);
		}
     //具体判断应该返回的最小正整数
     //如果经过 最终的数组的长度为1时
		if (newNums.length == 1) {
			if (newNums[0] == 1) {
				return (newNums[0] + 1);
			} else {
				return 1;
			}
		}
	//1不存在时
		if (newNums[0] != 1) {
			return 1;
		}
	//1存在时
		if (newNums[0] == 1) {
			for (int i = 0; i < newNums.length - 1; i++) {
				if (newNums[i] != (newNums[i + 1] - 1)) {
					return newNums[i] + 1;	//不全部连续时,间断点位置元素+1
				}
			}
			return (newNums[newNums.length - 1] + 1);	//全部连续时,结果为最后一个元素+1
		}
		return 0;
	}
}
  • 解法二:
class Solution {
		public int firstMissingPositive(int[] nums) {
		if (nums == null) {
			return 0;
		}
		if (nums.length == 0) {
			return 1;
		}
		if (nums.length == 1) {
			if (nums[0] == 1) {
				return (nums[0] + 1);
			} else {
				return 1;
			}
		}
	//	排序
		Arrays.sort(nums);
	//去除重复元素
		int index = 1;
		boolean flag1 = false;
		for (int i = 1, len = nums.length; i < len; i++) {
			if (nums[i] != nums[i - 1]) {
				nums[index++] = nums[i];
				flag1 = true;
			}
		}	
		if (flag1) {
			nums = Arrays.copyOf(nums, index);
		}
	//判断是否有1	
		boolean flag = false;
		for (int i = 0; i < nums.length; i++) {
			if (nums[i] == 1) {
				flag = true;
			}
		}
		if (!flag) {
			return 1;
		}
	//数组元素连续 结果为最后一个元素+1
		boolean flag2 = false;
		for (int i = 0; i < nums.length - 1; i++) {
			if (nums[i] != (nums[i + 1] - 1)) {
				flag2 = true;
			}
		}
		if (!flag2) {
			return (nums[nums.length - 1] + 1);
		}
	//数组元素不连续 结果为间断点元素+1
		int i;
		for (i = 0; i < nums.length - 1; i++) {
			if (nums[i] != (nums[i + 1] - 1)&&nums[i]>0) {
				break;
			}
		}
		return (nums[i] + 1);
	}
}

  • 解法三:
将原数组遍历 元素按照元素值存放在相应下边的一个新数组中
遍历新数组 判断新数组中第一个元素为0
返回其下标就是结果

class Solution {
	public int firstMissingPositive(int[] nums) {
		if (nums == null) {
			return 0;
		}
		if (nums.length == 0) {
			return 1;
		}
		Arrays.sort(nums);
		int[] record = new int[(nums[nums.length - 1])+2];
		for (int i = 0; i < nums.length; i++) {
			if (nums[i] > 0&&record[(nums[i])]==0) {
				record[(nums[i])] = nums[i];

			}
		}
		for(int i=1;i<record.length;i++) {
			if(record[i]==0) {
				return i;
			}
		}
		return 0;
	}
}

解法三 代码解释:
LeetCode41. 缺失的第一个正数(java)

  • 粘贴别人代码:
class Solution {
    public int firstMissingPositive(int[] nums) {
        if(nums.length == 0){
            return 1;
         }
        //第i位存放i+1的数值
        for(int i = 0; i < nums.length;i++){
            if(nums[i] > 0){//nums[i]为正数,放在i+1位置
                //假设交换的数据还是大于0且<i+1,则放在合适的位置,且数据不相等,避免死循环
                //这个while是关键,其它都是没有难度的
                while(nums[i] > 0 && nums[i] < i+1 && nums[i] != nums[nums[i] -1]){
                    int temp = nums[nums[i]-1];//交换数据
                    nums[nums[i]-1] = nums[i];
                    nums[i] = temp;
                }
            }
        }
        //循环寻找不符合要求的数据,返回
        for(int i = 0; i < nums.length;i++){
            if(nums[i] != i+1){
                return i+1;
            }
        }
        //假设都符合要求,则返回长度+1的值
		return nums.length + 1;
    }
}