【Leetcode】41. 缺失的第一个正数

题目描述

在这里插入图片描述

// 41. 缺失的第一个正数

// 给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
// 进阶:你可以实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案吗?


题解

// 暴力排序法
// 排序,定义结果保存位res=1,从头往尾遍历元素nums[i],如果元素等于res,
// res累加1。
// 执行用时:4 ms, 在所有 Java 提交中击败了6.63%的用户
// 内存消耗:84.6 MB, 在所有 Java 提交中击败了5.00%的用户
class Solution {
    public int firstMissingPositive(int[] nums) {
        Arrays.sort(nums);
        int res = 1;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == res) {
                res++;
            }
        }
        return res;
    }
}


// 计数排序法
// 由于要找正数,正数从1开始数起,我们希望像计数排序那样index对应的元素
// 设置为相同的元素,比如索引0对应元素0,索引1对应元素1。但是元素只从1开始
// 所以只好索引0元素1,索引1对应元素2,有:
// 索引: 0 1 2 3 4 ...
// 数组:[1,2,3,4,5...]
// 
// 所以索引i对应元素nums[i] - 1,或者说nums[i]元素应该对应索引i+1。
// 如果我们有nums[i]元素,那nums[i]元素本来应该在的位置索引应为nums[nums[i]-1]
// (【索引i对应元素nums[i] - 1]】规则下,两边加上nums[]就有:【元素nums[i]
// 对应位置nums[nums[i] - 1])
// 所以如果当前元素nums[i]和索引i不满足对应关系。那nums[i]本来应该在的位置
// 为nums[nums[i] - 1]。
// 
// 知道了这点之后我们for循环遍历数组,遍历元素为nums[i],在保证数组不越界
// 前提下,如果i与nums[i] - 1不相等,且nums[i]与nums[nums[i] - 1]不相等
// 则相应索引上的元素不对,while循环交换i和nums[i]-1的元素。
// 遍历完之后,第二个for循环,逐个遍历nums数组元素nums[i] 判断是否i
// 与nums[i] - 1相等,如果不相等,说明对应元素正数缺失,直接返回该正数
// i+1。否则说明nums给的正数都是连续的,没有中间正数缺失的情况,则缺失的
// 正数就是nums出现的连续正数的下一个正数,即nums.length + 1
// 
// 执行用时:1 ms, 在所有 Java 提交中击败了72.97%的用户
// 内存消耗:84 MB, 在所有 Java 提交中击败了5.64%的用户
class Solution {
    public int firstMissingPositive(int[] nums) {
		int len = nums.length;
		for (int i = 0; i < len; i++) {
			while (nums[i] >= 1 && nums[i] <= len && i != nums[i] - 1 && nums[i] != nums[nums[i] - 1]) {
				swap(nums, i, nums[i] - 1);
			}
		}
		for (int i = 0; i < len; i++) {
			if (i != nums[i] - 1)
				return i + 1;
		}
		return nums.length + 1;
    }
	
	public void swap(int[] nums, int i, int j) {
		if (i != j) {
			int temp = nums[i];
			nums[i] = nums[j];
			nums[j] = temp;
		}
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

锥栗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值