41.缺失的第一个正数(哈希表)

在这里插入图片描述
解法:原地哈希

将数组中的数字 x x x,映射到数组中的位置 x − 1 x-1 x1

考虑极端情况:

(1)数组长度为 N N N,是从 1 1 1开始的正整数序列,如 1 , 2 , 3 , . . . , N , 1,2,3,...,N, 1,2,3,...,N,则没出现的那个最小的正整数为 N + 1 N+1 N+1
(2)数组长度为 N N N,不含 [ 1 , N ] [1,N] [1,N]范围的任何数字,则没有出现的最小正整数为 1 1 1

除了(1)这种极端情况,没有出现的最小正整数必然在 [ 1 , N ] [1,N] [1,N]范围。

对于长度为 N N N的数组,映射完成后,在 [ 1 , N ] [1,N] [1,N]范围内的数字都映射到了合适的位置,而且是按从

小到大的顺序排列的。而其他数字(该范围内重复的数字,不在此范围的数字)占据了剩下的位置。

这时,只需要从数组序号 0 0 0的位置开始枚举,找到第一个不符合该哈希映射的数字所在位置,就

找到了没有出现过的那个最小的正数。

举个例子进行理解,来自评论区某有才老哥:

在这里插入图片描述

c语言版本代码:

void swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
int firstMissingPositive(int* nums, int numsSize){
    for(int i = 0; i<numsSize; i++)
    {
        // 映射规则,nums[i] --> nums[nums[i]-1]
        // nums[i]-1 作为数组下标应满足nums[i]-1>=0,即nums[i]>0
        // nums[i]-1 作为数组下标应满足nums[i]-1<numsSize,即nums[i]<=numsSize
        // 如果数组中有重复数,可能会出现nums[i] == nums[nums[i]-1]的情况,
        // 这时表明该数已放在正确的地方,及时跳出循环, 否则会陷入无限死循环
        
        while(nums[i] > 0 && nums[i] <= numsSize && nums[i] != nums[nums[i]-1] )
        {
            swap(&nums[i], &nums[nums[i]-1]);
        }
    }
    // 映射完后,数组i处的值应是i+1,若不是,则是没有出现过的那个最小的正数
    for(int i=0; i<numsSize; i++)
    {
        if(nums[i] != i+1)
        {
            return i+1;
        }
    }
    //如果数组是从1开始的正数序列,应该返回 numsSize+1
    //:[1,2,3],应该返回4.
    return numsSize + 1;    
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值