408真题-2018年数组中未出现的最小正整数

450 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 22 天,点击查看活动详情

Day51 2023/02/25

难度:简单

题目

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

示例1

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

示例1

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

思路


题目已经要求尽可能时间上高效,那本题就采用哈希法,典型的时间换空间的解法,用一个哈希表来记录待查找数组中每一个元素出现的次数,再从哈希表中查找次数为0的元素,该元素的key值就为最小正整数。
具体步骤:

  1. 遍历待查找数组,并用哈希表record记录下每个元素出现的次数,数组中不存在的元素默认出现次数为0。
  2. 从res = 1开始向后遍历,并以res作为哈希表record的key值,判断record[res]的值,如果为0,则找到了最小正整数,否则继续遍历下去。
  3. 返回最后结果res。

关键点


  • 要理解为什么从1开始向后连续遍历,例如:一串连续的正整数序列:1 2 3 4 5 6,其中抽走哪一个,哪一个就为这串序列中未出现的最小正整数,本题同理,相当于用record记录了哪一个元素被抽走。

算法实现


c++代码实现-哈希法

#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;
 }
  • 时间复杂度 O(n)O(n)--- 遍历了整个数组,其中n为数组的长度
  • 空间复杂度 O(n)O(n)--- 辅助数组的大小n,其中n为数组的长度

总结

  • 仅考虑时间复杂度的题目,一般都用时间换空间的解法,其中使用辅助数组的方式最是常见。