力扣网C语言编程题:缺失的第一个正数

一. 简介

本文记录力扣网上涉及数组方面的编程题,主要以 C语言实现。

二. 力扣网C语言编程题:缺失的第一个正数

题目:缺失的第一个正数

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

请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

示例 1:
输入:nums = [1,2,0]
输出:3
解释:范围 [1,2] 中的数字都在数组中。

示例 2:
输入:nums = [3,4,-1,1]
输出:2
解释:1 在数组中,但 2 没有。

示例 3:
输入:nums = [7,8,9,11,12]
输出:1
解释:最小的正数 1 没有出现。

提示:
    1 <= nums.length <= 105
    -231 <= nums[i] <= 231 - 1

解题思路 一:

通过示例可知,缺失的第一个正数的范围为 0 < data <= (n+1),这个分析结果很重要;

(1) 重新创建一个新的数组,用来标记原数组中元素;

因为获取的正整数,所以,原数组中负数不用考虑;当原数组中的元素大于 0时,则在对应新数组位置(原数组的元素作为新数组的index)标记1;

(2) 遍历新数组,查找数组中第一个不为1的元素,返回其 index即 为缺失的最小正整数;如果遍历结束没有找到则缺失的最小正整数为 n+1;

C语言实现如下:

#include <stdio.h>

#define MAX    300001
int hash_table[300001];

int firstMissingPositive(int* nums, int numsSize) {
        int index = 0;
        //这里必须首先将新数组都初始化为0
        memset(hash_table, 0, sizeof(hash_table));
        
        //因为缺失的最小正整数范围是 0< data <= n+1
        //遍历原来数组,当元素 0< < MAX 时,对应新数组位置设置标志1
        for(index = 0; index < numsSize; index++) {
            if(nums[index] > 0 && nums[index] < MAX) {
                hash_table[nums[index]] = 1;
            }
        }
        //遍历新数组,找到第一个不为 1的元素,其索引值index即为缺失的最小正整数
        for(index = 1; index <= numsSize; index++) {
            if(hash_table[index] != 1) {
                return index;
            }
        }
        //如果没有找到,则就是 numsSize+1
        return (numsSize+1);
}

可以看出,虽然实现了,但是没满足题目要求。这里实现的时间复杂度为 O(n),空间负责度也是 O(n)。

解题思路 二:

通过示例经过分析可知,所要查找的最小正整数范围一定在  0 < data <= n+1。

1. 首先,新创建一个数组,用于标记原数组元素是正数,还是负数;

2. 遍历原数组,根据原数组元素值标记新数组元素;

3. 遍历新数组,查找到第一个元素为1,即为缺失最小正整数;

4. 第三步遍历结束后如果找不到,则最小正整数为 (numsSize+1)。

C语言实现如下:

#include <stdio.h>

int firstMissingPositive(int* nums, int numsSize) {
    if((nums == NULL) || (!numsSize)) {
        return -1;
    }

    //创建一个新数组,用于标记原数组中元素是正数还是负数
    //该数组首先必须初始化一个值
    int i;
    int* hash_ptr = (int*)malloc((numsSize+1) * sizeof(int));
    for(i = 0; i < (numsSize+1); i++) {
        hash_ptr[i] = 1;
    }

    //遍历原数组,根据原数组元素值标记新数组元素
    for(i = 0; i < numsSize; i++) {
        if((nums[i] > 0) && (nums[i] <= numsSize)) {
            hash_ptr[nums[i]] = -1;
        }
    }
    
    //遍历新数组,查找到第一个元素为1,即为缺失最小正整数
    for(i = 1; i < (numsSize+1); i++) {
        if(hash_ptr[i] == 1) {
            return i;
        }
    }

    free(hash_ptr);
    hash_ptr = NULL;
    //如果找不到,则最小正整数为 (numsSize+1)
    return (numsSize + 1);
}

可以看出,虽然实现了,但是没满足题目要求。这里实现的时间复杂度为 O(n),空间负责度也是 O(n)。

下一篇文字学习一种空间复杂度为 O(1)的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值