思路及C++实现
没跑过,多半有bug,法1法2参考https://blog.csdn.net/stpeace/article/details/109544261
法3和法2类似但是比较好想,空间复杂度更高
//求数组中缺失的最小整数,法1,巧妙标记法,时间复杂度o(n),空间复杂度o(1)
int min_search_1(int input[], int n) {
for (int i = 0; i < n; i++)
{
if (input[i] <= 0) //将所有非正数转化为n+1,不影响判断
{
input[i] = n + 1;
}
}
for (int i = 0; i < n; i++) //对于数组A中的元素a,做以下处理
{
int count = abs(input[i]); //1.取绝对值,值为count
if (count<=n) //2.将数组A中的元素A[count-1]置为负数,表示count存在
{
if (input[count - 1] > 0)
input[count - 1] *= -1;
}
}
for (int i = 0; i < n; i++) //3.遍历标记后的数组,第一个为正的位置i,表示i+1不存在
{
if (input[i] > 0) //若全部存在,则input[n] = n,返回-1
{
return input[i] > n ? -1 : i + 1;
}
}
}
//求数组中缺失的最小整数,法2,置换归为法,时间复杂度o(n),空间复杂度o(1)
int min_search_2(int input[], int n) {
for (int i = 0; i < n; i++)
{
int temp = 0;
if (input[i]>0 && input[i]<n) //对于在0-n之间的正整数i
{
temp = input[input[i]-1]; //将i置换到第i个位置,即变为input[i-1]
input[input[i]-1] = input[i];
}
}
for (int i = 0; i < n; i++)
{
if (input[i] != i+1) //当下标i不等于值i+1时,说明不存在i+1
{
return i + 1;
}
else
{
return -1;
}
}
}
//求数组中缺失的最小整数,法3,列表标记法,时间复杂度o(n),空间复杂度o(n)
int min_search_2(int input[], int n) {
int mark[MaxSize]{};
for (int i = 0; i < MaxSize; i++)
{
mark[i] = 0;
}
for (int i = 0; i < n; i++) //将input数组中出现的所有数字x转化为mark数组mark[x]=1的标记
{
if (input[i]>0&&input[i]<n)
{
mark[input[i]] = 1;
}
}
for (int i = 1; i < MaxSize; i++) //mark数组第1个元素即mark[0]不在遍历范围内
{
if (mark[i] == 0)
{
return i;
}
}
}