题目:给定一个含n(n>=1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数。
例如,数组{-5,3,2,3}中未出现的最小正整数是1;数组{1,2,3}中未出现的最小正整数是4。
关键字顺序表 查找未出现的最小正整数
思路
关注:1.因为要求时间上尽可能高效,所以采用“空间换时间”的办法(开辟新空间来存放有关新数组)
2.关注造成最终结果产生变化的影响因素,倒推思路
分配一个用于标记的新数组B[n],用来记录A中是否出现了1~n中的正整数
B[0]对应了1,B[n-1]对应了正整数n,初始化B中全部为0(0为判断A是否取到数值等同于此时下标的整数的判断小助手,代表否)。
因为A一共就n个元素,所以最终得到的返回值只可能为1~n+1这n+1个整数,不可能为<=0(题设)以及>=n+2(分析)的整数的
(思路:如果想要返回值为X,那么必然原数组中1,2,…X-1都要取到至少一个)
a.当A中n个数恰为1~n,时返回n+1。
b.当A中出现了<=0或者>=n+1的元素时,返回值为1~n中没有被取到的那些个中最小的那个。体现在算法上,则B【相对应的i】=0,相当于原值,所以不做任何处理
c.当A中出现了1~n中的元素时,将B【相对应的i】=1
需要变量:A[],B[], 遍历下标:i,(一个下标足够,B的下标由A的实际取值来代表)
步骤
1.从A[0]开始遍历扫描,
a.若0<A[i]<=n,则令B[A[i]-1]=1
(eg: A[i]=1,则B[0]=1;A[i]=5,则B[4]=1)
b.若A[i]<=0||A[i]>=n+1,不动
2.遍历扫描A结束之后自动完成B的赋值,此时开始遍历扫描B
a.若B[i]==1,返回i+1
b.若else,返回n+1
int findMissMin(int A[],int n){
int i,*B //标记数组
B=(int*)malloc(sizeof(int)*n);//分配空间给B,*是乘号
memset(B,0,sizeof(int)*n;)//赋初值给B,全部元素都为0
for(i=0;i<n;i++)
if(A[i]>0 && A[i]<=n)//若A[i]的值介于1~n,则标记数组B
B[A[i]-1]=1;
for(i=0;i<n;i++)//扫描数组B,找到目标值
if(B[i]==0) break;
return i+1;//返回结果
}