题目描述:
【2018统考真题】给定一个含n(n>=1)个整数的数组,请设计一个在时间上尽可能高效的
算法,找出数组中未出现的最小正整数。例如,数组{-5,3,2,3}中未出现的最小正整数
是1;数组{1,2,3}中未出现的最小正整数是4。要求:1)给出算法的基本设计思想。
2)根据设计思想,采用 C 或 C++ 语言描述算法关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度。
1)思路:
为追求时间上尽可能高效,则申请一个辅助数组 大小和给定数长相等初始化为0,用来标记所出现的过的正整数,对应位置设为1。如若给定数中出现了小于0或者大于长度n的值,那么数组中一定会出现空缺位置,即未出现的最小正整数一定在辅助数组里;如若所有元素都为正整数且小于等于n,那么最小正整数就是n+1。
2)具体实现:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//2018 统考真题
//题目:找出数组中未出现的最小正整数
typedef int ElemType;
typedef struct{
ElemType *data;
int TableLen;
}SqList; //动态分配
void InitList (SqList &L,int len)//初始化顺序表
{
L.TableLen = len;
L.data = (ElemType*)malloc(sizeof(ElemType)*L.TableLen);
int i;
srand(time(NULL)); //随机取值
for (i = 0;i < L.TableLen ; i++)
{
L.data[i] = rand()%10;
}
}
void print_list(SqList L)//打印函数
{
for(int i = 0; i<L.TableLen ;i++)
{
printf("%-3d",L.data[i]);
}
printf("\n");
}
ElemType NotFindInt(SqList L,int n)
{
ElemType *B; //标记数组用来标记已有元素
B = (ElemType*)calloc(n+1,sizeof(ElemType));
int i;
for (i = 0;i < n;i++)
{
if(L.data[i] > 0 && L.data[i]<=n)//只标记小于数组长度的正整数
B[L.data[i]] = 1;//遍历数组用标记数组的下标记录出现的元素
}
i=1;
while(B[i]!=0) i++;
return i; //返回数组下标
}
int main() {
SqList L;
InitList(L,5);
print_list(L);
ElemType e;
e = NotFindInt(L,5);
printf("%d",e); //打印未出现的最小正整数
return 0;
}
3)复杂度:
因为只对两数组分别进行了一次遍历,则时间复杂度为 O(n); 而申请了一个大小为n的辅助数组,故空间复杂度为O(n)。
运行结果:
ps:为了省事我从数组下标为1开始,申请了n+1的大小