C++ c++;在未排序的数组中查找第一个缺少的正值
我试图理解在未排序的数组中找到第一个缺失正值的解决方案。它是这样工作的 1,找到输入的最小值和最大值,并用 特殊正值。 2.在确保最小值以1开始(否则我们知道“1”丢失)之后,我们扫描输入,类似于计数排序,因为我们不能 使用额外的空间。我无法将这些值标记为负值来表示 吃角子老虎了 3.在valMin和valMax之间扫描我们刚刚计算的输入范围,如果我们可以确定任何插槽未被占用(如中为正值),则我们 知道那是丢失号码的位置 我的问题是这两条线在做什么C++ c++;在未排序的数组中查找第一个缺少的正值,c++,algorithm,C++,Algorithm,我试图理解在未排序的数组中找到第一个缺失正值的解决方案。它是这样工作的 1,找到输入的最小值和最大值,并用 特殊正值。 2.在确保最小值以1开始(否则我们知道“1”丢失)之后,我们扫描输入,类似于计数排序,因为我们不能 使用额外的空间。我无法将这些值标记为负值来表示 吃角子老虎了 3.在valMin和valMax之间扫描我们刚刚计算的输入范围,如果我们可以确定任何插槽未被占用(如中为正值),则我们 知道那是丢失号码的位置 我的问题是这两条线在做什么 int &val = nums[abs
int &val = nums[abs(num) - valMin];
if (val > 0) val = -val;
例如,如果您的输入数组是{1,-3,2,1,4,3}代码>
在此点之后,数组变为-1,-2147483647,-2,-1,4,3
#include <iostream>
#include <algorithm>
#include <vector>
#include <limits.h>
using namespace std;
int firstMissingPositive(vector<int> &A) {
int valMin = INT32_MAX, valMax = 0;
for (auto &num:A) {
if (num > 0) {
valMin = min(valMin, num);
valMax = max(valMax, num);
} else {
num = INT32_MAX;
}
}
for (auto &num:A)
cout << num << ",";
cout << "\n";
if (valMin != 1) return 1;
for (int &num:A) {
if (num != 0 and abs(num) != INT32_MAX) {
int &val = A[abs(num) - valMin];
if (val > 0) val = -val;
}
}
for (auto &num:A)
cout << num << ",";
//scan the range the input where we just did count on between valMin and valMax,
//if we can any slot isn’t taken (as in is positive) then we know that’s the slot where the missing number is.
for (int i = valMin; i < valMax; ++i) {
if (A[i - valMin] > 0) return i;
}
return valMax + 1;
}
int main()
{
std::vector<int> v = { 1, -3, 2, 1, 4, 3 };
int answer = firstMissingPositive(v);
cout << answer;
return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
int firstMissingPositive(向量&A){
int valMin=INT32_MAX,valMax=0;
用于(自动编号:A(&N){
如果(数值>0){
valMin=min(valMin,num);
valMax=max(valMax,num);
}否则{
num=INT32_MAX;
}
}
用于(自动编号:A(&N)
cout其思想是将数字n
的存在信息编码为位置a[n-valMin]
中数字的符号
-1,-2147483647,-2,-1,4,3
这里我们看到1,2,3,4是存在的,因为前4个数组元素有负号。所以,第一个缺少的正数是5。这里
因为我们不能使用额外的空间。我可以将值标记为负数,以指示插槽已占用
解决方案是使用相同的输入数组来标记所使用的插槽
这些线路:
int&val=nums[abs(num)-valMin];
如果(val>0)val=-val;
abs(num),因为可能存在类似{0,-4,-5,6,1,2,3}的情况,所以在迭代之前将“2”标记为“-2”
这些线路是,
在索引'num'-1处获取值,本质上,因为valMin将始终为1,否则它将返回函数
然后检查该值是否为正值,这意味着该索引以前从未被逻辑检查过,否则它将为负值。因此,如果该值为正值,则make为负值,以标记数组中存在与该索引对应的值
因此,例如,在输入数组中,迭代将如下所示:
0.0,最大,1,1,1,2,3,3}<
{{0,最大,0 0,-0-4-4,-4,-5,5,5,6,6,6,6,6,6,6,1,1,1,1,1,1,2,2,2,2,3}{{0,0,0,0,0,0,0,最大,1,1,1,1,2,2,3 3}<<0<<<
{{{{00,0,0,0,最大,0,最大,最大,0,最大,最大,最大,最大,最大,最大,最大,最大,最大,最大,最大,0,最大,最大,最大,最大,最大,最大,最大,最大,最大,最大,最大,最大,<6<强>6<强>6<<强>6<<强>>>>,0,0,0,0,0,0,6<3}=>{0,-MAX,-MAX,6,1,-2,3}
然后,如果(A[i-valMin]>0)返回i;
将检查第一个为正的条目,即i-valMin
或者我应该说i-1
。因此,本质上,第一个为正的索引+1
就是答案
这里,在示例输入数组中,{0,-MAX,-MAX,6,1,-2,3}
;第一个正索引是3,所以答案是3+1,即4,这也是一个完全的垃圾循环;因为如果你传递向量[1100,200,300]
,你会发现它崩溃了。(您会注意到,它试图编辑索引数组中的项,因此,通过使用这些较大的数字,它将尝试编辑超出边界的数据),它应该确保该值在向量大小的范围内,并且是!=0或+/-INT32_MAX@UKMonkey[1100200300]
似乎工作正常?尝试将其替换为.at()
而不是[]
,您将看到异常被抛出。