day52 计算机考研408真题2018年41题(C++)

202 阅读2分钟

题目来源: 计算机考研408真题2018年41题

题目描述:

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

  • 示例:

输入:-5,3,2,3
输出:1

输入:1,2,3
输出:4

思路:空间换时间

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

具体实现:

#include <iostream>
#include <cstring>
using namespace std;

int findMissin(int arr[], int n) {
    int i, *B;
    B = (int *) malloc(sizeof(int) * n);
    memset(B, 0, sizeof(int) * n);     //将数组B全部初始化为0
    for (i = 0; i < n; i++)
        if (arr[i] > 0 && arr[i] <= n)  //仅仅对数组arr中在(0,n]范围内的数据进行操作
            B[arr[i] - 1] = 1;          //将其放入数组B中
    for (i = 0; i < n; i++) {           //对数组B进行遍历,检查是否有存储元素为0
        if (B[i] == 0)
            break;                      //如果有存储元素为0,那么便找到了最小的正整数
    }
    return i + 1;                      //如果上面对数组B的遍历后,数组B所有的元素都为1,
                                    //说明最小正整数是n+1
}

int main() {
    int arr[] = {-5,2,3};
    int res = findMissin(arr, 3);
    cout<<res;   //输出结果为1
}

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