Day48:数组中未出现的最小正整数

260 阅读2分钟

题源:[2018统考真题]

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

例如,数组{-5, 3, 2, 3}中未出现的最小正整数是1;数组{1, 2,3}中未出现的最小正整数是4。

要求:

1)给出算法的基本设计思想

1.建立一个辅助数组用来记录当前数组的信息;
2.把非正数和大于数组长度的数设为非法值,因为题目要求的未出现的最小正整数,所以非正数是非法值;
3.为什么把大于数组长度的数设为非法值呢?是因为大于数组长度的数是不会影响求未出现的最小正整数的;
举个例子:{1,8,8,8}中未出现的最小正整数为2并不会受到8的影响
          {1,2,3,4}中4小于等于数组长度,所以会影响未出现的最小正整数的值,如果把4改成5,6,7等大于数组长度的值,会发现最小正整数的值仍为4;
 4.如果目标数组出现1就把他存在辅助数组的第一个位置,3就存在第二个位置     
 5.最后查找辅助数组,若辅助数组为{0,2,3}则说明原数组中出现过若干个2,3,则输出1(下标+1)
                     若辅助数组为{1,2,3}则说明原数组出现过若干个1,2,3,则输出4(数组长度)

2)根据设计思想,采用C或C+ +语言描述算法,关键之处给出注释。


static int minnumber(int arr[]){
    int ans[] = new int[arr.length];
    int index = 0;
    for (int i = 0;i < arr.length;i++){
        if (arr[i] > 0 && arr[i] <= arr.length){
        //如果目标数组出现1就把他存在辅助数组的第一个位置,3就存在第二个位置 
            ans[arr[i]-1] = arr[i];
        }
    }
   for (int i = 0; i < arr.length;i++){
   //最后查找辅助数组,若辅助数组为{0,2,3}等类似情况则说明原数组中出现过若干个2,3,则输出1(下标+1)
       if (ans[i] == 0)return i+1;
   }
   //若辅助数组为{1,2,3}则说明原数组出现过若干个1,2,3,则输出4(数组长度)
   return arr.length+1;
}

3)说明你所设计算法的时间复杂度和空间复杂度

时间复杂度:O(n);

空间复杂度:O(n);