您现在的位置是:主页 > news > 苏州建网站/百度营销

苏州建网站/百度营销

admin2025/6/16 10:59:34news

简介苏州建网站,百度营销,网站程序制作软件,广东网站建设公司NC30 数组中未出现的最小正整数 给出一个长度为 nnn 的数组 arrarrarr,找出未在 arrarrarr 中出现的最小的正整数。 比如以下几组输入: arr[1,2,3,4]arr[1,2,3,4]arr[1,2,3,4],答案为 5。arr[2,3,4,5]arr[2,3,4,5]arr[2,3,4,5],…

苏州建网站,百度营销,网站程序制作软件,广东网站建设公司NC30 数组中未出现的最小正整数 给出一个长度为 nnn 的数组 arrarrarr,找出未在 arrarrarr 中出现的最小的正整数。 比如以下几组输入: arr[1,2,3,4]arr[1,2,3,4]arr[1,2,3,4],答案为 5。arr[2,3,4,5]arr[2,3,4,5]arr[2,3,4,5],…

NC30 数组中未出现的最小正整数

给出一个长度为 nnn 的数组 arrarrarr,找出未在 arrarrarr 中出现的最小的正整数。

比如以下几组输入:

  • arr=[1,2,3,4]arr=[1,2,3,4]arr=[1,2,3,4],答案为 5。
  • arr=[2,3,4,5]arr=[2,3,4,5]arr=[2,3,4,5],答案为 1。
  • arr=[−1,4,1,4]arr=[-1,4,1,4]arr=[1,4,1,4],答案为 2。

方法一:暴力枚举

不难发现,对于长度为 nnnarrarrarr,最多包含 nnn 个正整数,所以缺失的最小正整数 xxx 必然满足 1≤x≤n+11\le x \le n+11xn+1

一个很直观的思路是:枚举 i∈[1,n+1]i∈[1, n+1]i[1,n+1],检查 iii 是否存在于 arrarrarr 中。

时间复杂度:O(n2)O(n^2)O(n2)

空间复杂度:O(1)O(1)O(1)

class Solution {
public:int minNumberdisappered(vector<int>& arr) {int x = -1;for (int i = 1; i <= arr.size()+1 && anw == -1; i++) {bool find = false;for (int j = 0; j < arr.size() && find == false; j++) {if (arr[j] == i) find = true; }if (!find) x = i;}return x;}
};

方法二:哈希

方法一中,每查找一次 iii 的时间复杂度为 O(n)O(n)O(n),考虑借助标记数组优化查找过程。

首先,定义长度为 n+1n+1n+1 的标记数组 markmarkmark,并全部初始化为 falsemarkmarkmark 的含义为:若 markimark_imarkifalse,则说明 i+1i+1i+1 不存在,反之则存在。

std::vector<bool> mark(arr.size()+1, false);

接下来,遍历 arrarrarr,并更新 markmarkmark,该过程的时间复杂度为 O(n)O(n)O(n)

for (auto d : arr) {if (1 <= d && d <= arr.size()+1) {mark[d-1] = true;}
}

考虑到答案的取值范围为 [1,n+1][1,n+1][1,n+1],所以在更新过程中过滤了区间之外的值。这样在保证正确性的前提下,也避免了发生「访问数组越界」的问题。

最后,枚举i∈[1,n+1]i∈[1,n+1]i[1,n+1],并检查 marki−1mark_{i-1}marki1 是否为 false。每次检查的时间复杂度为 O(1)O(1)O(1),整个检查过程的时间复杂度为 O(n)O(n)O(n)

for (int i = 1; i <= arr.size()+1; i++) {if (mark[i-1] == false) {return i;}
}

整个过程的复杂度为:

  • 时间复杂度:O(n)O(n)O(n)
  • 空间复杂度:O(n)O(n)O(n)

完整代码如下:

class Solution {
public:int minNumberdisappered(vector<int>& arr) {std::vector<bool> mark(arr.size()+1, false);for (auto d : arr) {if (1 <= d && d <= arr.size()+1) {mark[d-1] = true;}}for (int i = 1; i <= arr.size()+1; i++) {if (mark[i-1] == false) {return i;}}return -1;}
};

方法三:不使用标记数组的哈希

考虑到答案的取值范围为 [1,n+1][1,n+1][1,n+1],因此将 arrarrarr 中不在该区间的元素都置为 n+2n+2n+2 也不会影响正确性。

for (auto &c : arr) {if (c < 1 || c > arr.size()) {c = arr.size()+2;}
}

经过上述处理后,arrarrarr 中的元素均为正整数,那么可使用「正负」来表示某个数字是否存在:

  • arriarr_iarri 为负表示数字 i+1i+1i+1 存在于 arrarrarr 中,反之不存在。
  • ∣arri∣|arr_i|arri,即 arriarr_iarri 的绝对值才是 arriarr_iarri 真正的值。

接下来,再次遍历 arrarrarr,并更新 arrarrarr 中个元素的正负。

for (auto c : arr) {int ori = abs(c); // 取出真正的值if (ori != arr.size()+2) {arr[ori-1] = -abs(arr[ori-1]); // 并将 arr[ori-1]置为负数。}
}

最后,遍历 arrarrarr,找出第一个满足 arri>0arr_i \gt 0arri>0iii,则 i+1i+1i+1 即为答案。如果不存在这样的 iii,则答案为 n+1n+1n+1

时间复杂度:O(n)O(n)O(n)

空间复杂度:O(1)O(1)O(1)

class Solution {
public:int minNumberdisappered(vector<int>& arr) {for (auto &c : arr) {if (c < 1 || c > arr.size()) {c = arr.size()+2;}}for (auto c : arr) {int ori = abs(c);if (ori != arr.size()+2) {arr[ori-1] = -abs(arr[ori-1]);}}for (int i = 0; i < arr.size(); i++) {if (arr[i] >= 0) {return i+1;}}return arr.size()+1;}
};