【蓝蓝计算机考研算法】-day17-数组中未出现的最小正整数

122 阅读2分钟

23、数组中未出现的最小正整数

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

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

示例

输入:{-5, 3, 2, 3}
输出:1
说明:数组中未出现的最小正整数就是1

思路

可以直接提取这样几个关键词

  • 使用数组,求未出现的最小正整数
  • 看到数组,是不是想到是否有序
  • 时间+空间尽可能高效
    题目已经要求尽可能时间上高效,那本题就采用哈希法,典型的时间换空间的解法,用一个哈希表来记录待查找数组中每一个元素出现的次数,再从哈希表中查找次数为0的元素,该元素的key值就为最小正整数。
    具体步骤:
  1. 遍历待查找数组,并用哈希表record记录下每个元素出现的次数,数组中不存在的元素默认出现次数为0。
  2. 从res = 1开始向后遍历,并以res作为哈希表record的key值,判断record[res]的值,如果为0,则找到了最小正整数,否则继续遍历下去。
  3. 返回最后结果res。

具体实现

哈希法

#include <iostream>
#include <unordered_map>
#include <vector>

using namespace std;

/**
 * @function 找出数组中未出现的最小正整数
 * @param arr vector数组容器 待查找数组
 * @return 整型 该数组未出现的最小正整数
  */
int FindMinPI(vector<int> arr) {
    unordered_map<int, int> record; // 辅助的记录表
    int res = 1; // 数组中未出现的最小整数 
    for (int val : arr) record[val]++; // 记录数组中每个元素出现次数
    while (record[res]) res++; // 找出最小正整数,record中出现次数为0就是
    return res;
}

//测试一下
int main() {
    vector<int> arr = {-5, 3, 2, 3}; // 数据1
   // vector<int> arr = { 1, 2, 3 }; // 数据2
    int res = FindMinPI(arr);
    cout << "该数组中未出现的最小正整数为:" << res;
    return 0;
}

运行结果

image.png

复杂度

  • 时间复杂度O(n)--- 遍历了整个数组,其中n为数组的长度
  • 空间复杂度O(n)--- 辅助数组的大小n,其中n为数组的长度