题目
给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。
示例 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;
}