题目描述
给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。
示例 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)这个数发生在1-n+1的位置,n个连续的数,就算找到最后也就是这个啦,抽题原理
(2)看看数组能不能原地利用
(3)比0小或者比n+1大的,就不考虑了。
(4)找人代替visit,用-值表示某些值出现过
(5)把原先的负数处理掉,都变成1,
(6)那原来里面有1吗?没有就返回1,
(7)我们不怕重复标记的,反正就是有正数的位置,出现了我们就把它存为负数,
从底向上,
详细解释关注 B站 【C语言全代码】学渣带你刷Leetcode 不走丢 https://www.bilibili.com/video/BV1C7411y7gB
C语言完全代码
#include <stdio.h>
#include <stdlib.h>
int firstMissingPositive(int* nums, int numsSize)
{
int* visit=(int*)malloc((numsSize+1)*sizeof(int));
int i;
for(i=0; i<numsSize+1; i++) visit[i]=0;
for(i=0; i<numsSize; i++)
if(nums[i]>0&&nums[i]<=numsSize)
visit[nums[i]-1]=1;
for(i=0; i<numsSize+1; i++)
if(visit[i]==0) break;
return i+1;
}
int firstMissingPositive1(int* nums, int numsSize)
{
int i;
int has1=0;
//1,2,查找是否含有1,并且将小于1,大于numsSize 的数字全部修改为1
for (i = 0; i < numsSize; i++)
{
if (nums[i] == 1)
{
has1 = 1;
}
else if ((nums[i] <= 0) || (nums[i] > numsSize))
{
nums[i] = 1;
}
}
if (!has1) return 1;
int temp;
//3,遍历修改后的数组,用数字作为下标,将数组对应位置的元素修改符号
for (i = 0; i < numsSize; i++)
{
temp = (abs(nums[i]))%numsSize;
if (nums[temp] > 0)
{
nums[temp] = 0 - nums[temp]; //变成负数
}
}
//4,遍历数组,找到第一个正数,下标即为没有出现的最小正整数
for (i = 1; i < numsSize; i++)
{
if (nums[i] > 0)
{
break;
}
}
if ((i >= numsSize) && (nums[0] < 0))
{
return numsSize + 1;
}
else
{
return i;
}
return i+1;
}
int main()
{
int numsSize;
scanf("%d",&numsSize);
int nums[numsSize];
int i;
for(i=0; i<numsSize; i++)
{
scanf("%d",&nums[i]);
}
int result=firstMissingPositive(nums, numsSize);
printf("%d\n",result);
int result1=firstMissingPositive1(nums, numsSize);
printf("%d\n",result1);
return 0;
}