缺失的第一个正数

题目描述

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

示例1

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

示例2

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

示例3

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

说明

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

思路

提供两种思路:

  • hash 计数:需要额外的空间。所有出现的数字,hash 值 + 1。第二次从 1 开始查找 hash 表,找不到就是它了。但是这种方案不符合题意,而且 hash 计数这个方案效率也不是最优的。
  • 假设原始数组为 A。先构造一个临时数组 tmp,初始化为 0,大小为A.size(). 遍历 A,把 A[i] 复制到 tmp[A[i]-1] 的位置。如果 A[i] - 1 超过了 tmp 的范围,就直接扔掉。如此一来,tmp[0...size) 中就保存了一部分 A 的值。然后从位置 0 开始检查 tmp,如果发现该位置的值和索引号不匹配,就说明找到了缺失的数了。

注意上面的方案一,没办法优化成 in-place 算法,但是方案二可以。方案二,可以不使用 tmp 数组,直接在原始数组中操作,把每个数放到正确的位置。

我们使用一种 “座位交换法" 来达到 in-place 的目的:

  • 从第一个位置开始,让座位上的乘客走到自己应该坐的位置,并让该位置的人坐到第一个位置。一直进行这样的操作,直到第一个位置的人坐到自己位置。不过有时候我们知道,有的人总喜欢逃票。因此终止条件就是,一旦发现第一个位置的人逃票(票号 <= 0,或 >= 最大座位号),则终止交换。
  • 对第二到N个位置做相同的操作。

实现

int firstMissingPositive(vector<int>& nums) {

	if (nums.size() == 0)
	{
		return 1;
	}

	for (int i = 0; i < nums.size(); i++)
	{
		while (nums[i] > 0 && nums[i] <= nums.size() && nums[i] != nums[nums[i] - 1])
        //最后一个判断条件神了
		{
			swap(nums[i], nums[nums[i] - 1]);
		}
	}

	for (int i = 0; i < nums.size(); i++)
	{
		if (nums[i] != i + 1)
		{
			return i + 1;
		}
	}

	return nums.size() + 1;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值