数据结构_算法实现顺序表相关问题_13

一、问题描述:

给定一个含n(n>=1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数。例如,数组{-5,3,2,3}中未出现的最小正整数是1;数组{1,2,3}中未出现的最小正整数是4,要求:

  • 给出算法的基本设计思想。
  • 根据设计思想,采用C或C++语言描述算法,关键之处给出注释。
  • 说明你所设计算法的时间复杂度和空间复杂度。

二、算法思想:

要求在时间上尽可能高效,因此采用空间换时间的办法。分配一个用于标记的数组B[n],用来记录A中是否出现了1~n中的正整数,B[0]对应正整数1,B[n-1]对应正整数n,初始化B中全部为0。由于A中含有n个整数,因此可能返回的值是1 ~ n+1,当A中n个数恰好为1 ~ n时返回n+1.当数组A中出现了小于等于0或大于n的值时,会导致1 ~ n中出现空余位置,返回结果必然在1 ~ n中,因此对于A中出现了小于等于0或大于n的值,可以不采取任何操作。

经过以上分析可以得出算法流程:从A[0]开始遍历A,若0<A[i]<=n,则令B[A[i] - 1] = 1;否则不做操作。对A遍历结束后,开始遍历数组B,若能查找到第一个满足B[i] == 0的下标i,返回i + 1即为结果,此时说明A中未出现的最小正整数在1 ~ n之间。若B[i]全部不为0,返回i + 1(跳出循环时 i = n,i + 1等于n + 1),此时说明A中未出现的最小正整数是n + 1.

三、算法代码:

int findMissMin(int A[],int n)
{
    
    
	int i,*B;//标记数组
	B = (int *)malloc(sizeof(int) * n);//分配空间
	memset(B,0,sizeof(int) * n);//赋初值为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;//返回结果
}

四、算法复杂度:

  • 时间复杂度:遍历A一次,遍历B一次,两次循环内操作步骤为O(1)量级,因此时间复杂度为O(n)。
  • 空间复杂度:额外分配了B[n],空间复杂度为O(n)。

五、扩展memset函数:

C 库函数 void *memset(void *str, int c, size_t n) 复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。

参数:

  • str – 指向要填充的内存块。
  • c – 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
  • n – 要被设置为该值的字符数。

返回值:

  • 该值返回一个指向存储区 str 的指针。

memset赋值时只能赋值为0?

  • 答案肯定不是,比如任意字符都是可以的,初始化成0是最常用的。int类型的一般都是赋值0或-1,其他的值都不行。

猜你喜欢

转载自blog.csdn.net/qq_56866000/article/details/132036138
今日推荐