如何以STL的方式在列表中找到最小的缺失整数
How to find the minimal missing integer in a list in an STL way
我想在给定的列表中找到最小缺失的正整数。也就是说,如果给定一个正整数列表,即大于0且有重复,如何从这些缺失的列表中找到最小的一个。
序列中至少有一个元素缺失。
例如给定
std::vector<int> S={9,2,1,10};
答案应该是3,因为缺失的整数是3,4,5,6,7,8,11,…最小值是3
我想到了这个:
int min_missing( std::vector<int> & S)
{
int max = std::max_element(S.begin(), S.end());
int min = std::min_element(S.begin(), S.end());
int i = min;
for(; i!=max and std::find(S.begin(), S.end(), i) != S.end() ; ++i);
return i;
}
这是O(nmlogn)的时间,但我不知道是否有一个更有效的c++ STL的方式来做到这一点?
这不是练习,而是我在做一组自我完善的问题,我发现这是一个非常有趣的问题。
您可以使用std::sort
,然后使用std::adjacent_find
与自定义谓词。
int f(std::vector<int> v)
{
std::sort(v.begin(), v.end());
auto i = std::adjacent_find( v.begin(), v.end(), [](int x, int y)
{
return y != x+1;
} );
if (i != v.end())
{
return *i + 1;
}
}
当不存在这样的元素时,例如当vector为空时,则保持开放
用O(n)时间和常数空间找到第一个缺失的正数
基本上,当你读取值a时,只需与S[a]交换,就像2应该与a[2]交换
class Solution {
public:
/**
* @param A: a vector of integers
* @return: an integer
*/
int firstMissingPositive(vector<int> A) {
// write your code here
int n = A.size();
for(int i=0;i<n;)
{
if(A[i]==i+1)
i++;
else
{
if(A[i]>=1&&A[i]<=n&& A[A[i]-1]!=A[i])
swap(A[i],A[A[i]-1]);
else
i++;
}
}
for(int i=0;i<n;i++)
if(A[i]!=i+1)
return i+1;
return n+1;
}
};
假设数据先排序:
auto missing_data = std::mismatch(S.cbegin(), S.cend()-1, S.cbegin() + 1,
[](int x, int y) { return (x+1) == y;});
编辑由于输入数据没有排序,最简单的解决方案是先对它们排序:
std::vector<int> data(S.size());
std::partial_sort_copy (S.cbegin(), S.cend(), data.begin(), data.end());
auto missing_data = std::mismatch (data.cbegin(), data.cend()-1, data.cbegin()+1,
[](int x, int y) { return (x+1) == y;});
你可以使用标准模板库c++的算法在你的代码中工作。
#include <algorithm> // std::sort
this std::sort
in algorithm:
std::vector<int> v={9,2,5,1,3};
std::sort(v.begin(),v.end());
std::cout << v[0];
我希望我明白你在看什么
您可以通过构建一组整数并将集合中看到的较大的整数相加,并将未看到的最小值保留为计数器来实现此目的。一旦有一个数字等于后者,遍历删除元素集合,直到有一个缺失的整数。
具体操作请参见下文。
template<typename I> typename I::value_type solver(I b, I e)
{
constexpr typename I::value_type maxseen=
std::numeric_limits<typename I::value_type>::max();
std::set<typename I::value_type> seen{maxseen};
typename I::value_type minnotseen(1);
for(I p=b; p!=e;++p)
{
if(*p == minnotseen)
{
while(++minnotseen == *seen.begin())
{
seen.erase(seen.begin());
}
} else if( *p > minnotseen)
{
seen.insert(*p);
}
}
return minnotseen;
}
如果你的序列是在一个向量中,你应该使用:
solver(sequence.begin(),sequence.end());
该算法在时间上为O(N),在空间上为O(1),因为它只使用一个计数器、常量大小的附加空间和几个迭代器来跟踪最小值。
复杂度(增长率阶数)算法只保留一个输入的子集,期望该子集相对于输入的增长率具有恒定的增长阶数,因此在空间上为O(1)。迭代的增长率是O(N+NlogK)其中K是看到较大数字的较大子序列的增长率。后者是前面提到的恒定增长率的子序列,即K=1,这导致算法的复杂度为O(N)。(见注释)
- 如何在 sqlite3 中的表中添加整数列表
- 通过在带有 C++ 的列表中添加连续元素来计算新的整数列表
- 最大数量.给定一个非负整数列表,排列它们以使它们形成最大的数字
- 有效比较整数列表与C++中给定的整数
- 输入正整数或负整数列表,以使用开关函数 c++ 确定数字是偶数还是奇数
- 如何使用整数列表在LLVM中初始化整数数组
- 如何扩展类模板整数列表
- 如何生成升序随机整数列表
- 从文本文件将整数读入简单的链表中.然后对整数列表进行气泡排序并读出到另一个文件
- 填充整数列表比填充整数向量快 100 倍
- 整数列表的交集-无法返回结果列表
- 解析整数列表以进行向量、映射或多映射
- 从整数列表中交叉检查整数运行时错误
- 用于处理 3 个整数列表的数据结构
- 访问与命令行参数关联的整数列表
- 将整数列表打印为逗号分隔的数字列表,每行最多 10 个
- 正在将整数列表读取到数组C++中
- 在C++中读取单个输入行中的整数列表
- 为什么我会超时(使用sstream解析用逗号分隔的整数列表)
- 使用连续的无符号整数列表初始化 std::vector<无符号 int>