【408计算机考研】|【2018统考真题-41】| 给定一个含 n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数

目录

  • 一、题目
  • 二、解答
  • 三、测试数据

一、题目

  给定一个含 n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算 法,找出数组中未出现的最小正整数。例如,数组{-5, 3, 2, 3}中未出现的最小正整数是 1;数组{1, 2, 3}中未出现的最小正整数是 4。要求:
 (1)给出算法的基本设计思想。
 (2)根据设计思想,采用 C 或 C++语言描述算法,关键之处给出注释。
 (3)说明你所设计算法的时间复杂度和空间复杂度。

二、解答

(1)由于对空间方面未做限制,采用空间换时间的方案 ;
(2)C++实现:

// -*- coding: utf-8 -*-
//  @ Date   : 2021/5/20 13:14
//  @ Author : RichardLau_Cx
//  @ file   : Richard.cpp
//  @ IDE    : Dev-C++
//  @ Source : Data_Structure

#include 
#include  
#include 

using namespace std;

int func(int *num, int n) {
	/** 核心功能算法部分 
	 * *num: 数组对应通过指针接受地址 
	 * n: 数组需要总长度 
	 */ 
	 
	int *cnt = (int *) malloc((n+1) * sizeof(int));  // C 库函数 void *malloc(size_t size) 分配所需的内存空间即n+1个(从1开始)int类型大小,并返回一个指向它的指针。 =》 开辟辅助空间(防止污染源数据) 
	memset(cnt, 0, (n+1) * sizeof(int));  // C 库函数 void *memset(void *str, int c, size_t n) 复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。 =》 初始化全0 
	
	for (int i=0; i < n; i++)
	{  // 遍历一遍并标记 
		if (num[i] > 0 && num[i] <= n)
		{  // 在(0, n]区间则对应cnt位置上标1 
			cnt[num[i]] = 1;  // 以num[i]值作为下标,对应置1 
		 } 
	 } 
	
	for (int i=1; i <= n; i++)
	{
		if (cnt[i] == 0)
		{  // 先找到标记为0的即目标最小正整数 
			free(cnt);  // 释放空间 
		
			return i;
		}
	 } 
	 
	free(cnt); 
	return n+1;  // 全部刚好一对一标记,则取辅助数组最后位置的下一个位置 
}

int main() {
	int n, num[99];  // 开辟测试使用的数组 
	
	cin >> n;
	
	for (int i=0; i < n; i++) {
		cin >> num[i];  // 初始化给定数组序列值 
	}
	
	cout << "未出现的最小正整数为:" << func(num, n) << endl;
	
	return 0;
} 

(3)时空复杂度(针对核心功能算法而言):

  • 时间复杂度:两个for循环,T(n) = O(n) + O(n) = O(2n) ~ O(n);
  • 空间复杂度:开辟了以n为数量级的辅助空间,S(n) = O(n)。

三、测试数据

【408计算机考研】|【2018统考真题-41】| 给定一个含 n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数_第1张图片
【408计算机考研】|【2018统考真题-41】| 给定一个含 n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数_第2张图片
【408计算机考研】|【2018统考真题-41】| 给定一个含 n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数_第3张图片

你可能感兴趣的:(数据结构,ACM,算法分析与设计,链表,c++,数据结构,算法,数组)