力扣算法题-41.缺失的第一个正数 C语言实现

题目

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

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

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

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/first-missing-positive

思路

第一种思路:
1、先进行数组的排序;排序函数qsort,要避免差值超过返回值范围的情况;
2、然后找到数字1,j 进行累加判断,直到数组和 j 变量不等,跳出循环;

第二种思路:
1、通过调换,将数组中的在value [1,numsSize]范围内的数字移动到nums[value-1]位子上;
2、从头遍历数组,若(下标+1)和值不对应则返回(下标+1);

第三个思路:
通过正负标记,标记对应位置上是否是存在 值=(下标+1);
1、将 0 和负数转换为 非[1,numSize] 范围内的数字;
2、获取数据值的绝对值(绝对值是为了保留值的大小,不可丢失,后面还要判断),若在value [1,numSize] 范围内,则将下标为 value-1 对应转换为 负值,绝对值大小不变;
3、从头遍历数组,若(下标+1)的值为正则返回(下标+1);

程序

int cmp(const void *a, const void *b){
    
    
    /*防止出现差值过大超过int范围,负数的排序对于后续查找没有影响,只要放在正数前面即可 */
    if(*(int*)a < 0 ){
    
    
        return -1;
    }else if(*(int*)b < 0){
    
    
        return 1;
    }
    return *(int*)a - *(int*)b;
}
int firstMissingPositive(int* nums, int numsSize){
    
    
    int i = 0, iflag = 0, j = 1;
    /*先排序*/
    qsort(nums,numsSize,sizeof(int),cmp);
    /*然后按照顺序进行查找*/
    for(; i< numsSize; i++){
    
    
        /*跳过重复的数字*/
        if(i < numsSize - 1 && nums[i] == nums[i+1]) continue;
        if(nums[i] == j){
    
    
            iflag = 1;
            j++;
        }else if(iflag){
    
    
           break;
        }
    }
    return j;
}
int firstMissingPositive(int* nums, int numsSize){
    
    
    int i,j,tmp;

    for(i=0;i<numsSize;i++){
    
    
        /*数组值在范围内,且不在对应位置上,则调换*/
        while(nums[i]>0 && nums[i]<=numsSize && nums[i] != nums[nums[i] - 1]){
    
    
            /*注意调换顺序*/
            tmp = nums[nums[i] - 1];
            nums[nums[i] - 1] = nums[i];
            nums[i] = tmp;
            
        }
    }
    for(i=0;i<numsSize;i++){
    
    
        if(nums[i] != i+1){
    
    
            break;
        }
    }
    return i+1;
}
int firstMissingPositive(int* nums, int numsSize){
    
    
    int i,j,tmp;

    for(i=0;i<numsSize;i++){
    
    
        if(nums[i]<=0 || nums[i] > numsSize){
    
    
            nums[i] = numsSize+1;
        }
    }

    for(i=0;i<numsSize;i++){
    
    
        tmp = abs(nums[i]);
        if(tmp>0 && tmp <= numsSize){
    
    
            nums[tmp - 1] = -abs(nums[tmp - 1]);
        }
    }
    for(i=0;i<numsSize;i++){
    
    
        if(nums[i] > 0){
    
    
            break;
        }
    }
    return i+1;
}

Guess you like

Origin blog.csdn.net/MDJ_D2T/article/details/109057396