首先,您需要对向量进行排序。使用std::sort进行排序。
std::lower_bound查找第一个大于或等于给定元素的元素。(元素必须至少部分有序)
从这里开始迭代,直到您有连续的元素。
处理重复项:一种方法是我采用的方式:在迭代时考虑连续且相等的元素。另一种方法是添加一个前提条件,即向量/范围包含唯一的元素。我选择前者,因为它避免了删除元素的问题。
以下是从已排序的向量中删除重复项的方法:
v.erase(std::unique(v.begin(), v.end()), v.end());
我的实现:
auto firstMissing(std::vector<int> const &v, int elem) -> int {
auto low = std::lower_bound(std::begin(v), std::end(v), elem);
if (low == std::end(v) || *low != elem) {
return elem;
}
while (low + 1 != std::end(v) &&
(*low == *(low + 1) || *low + 1 == *(low + 1))) {
++low;
}
return *low + 1;
}
以下是一般化的版本:
template <class It, class T = decltype(*std::declval<It>())>
auto firstMissing(It first, It last, T elem) -> T {
auto low = std::lower_bound(first, last, elem);
if (low == last || *low != elem) {
return elem;
}
while (std::next(low) != last &&
(*low == *std::next(low) || *low + 1 == *std::next(low))) {
std::advance(low, 1);
}
return *low + 1;
}
测试案例:
int main() {
auto v = std::vector<int>{13, 8, 3, 6, 10, 1, 7, 7, 7, 0};
std::sort(v.begin(), v.end());
for (auto n : {-2, 0, 5, 6, 20}) {
cout << n << ": " << firstMissing(v, n) << endl;
}
return 0;
}
结果:
-2: -2
0: 2
5: 5
6: 9
20: 20
关于排序的说明:根据OP的评论,他正在寻找一种不会修改向量的解决方案。
为了实现高效的解决方案,必须对向量进行排序。如果不想修改向量,可以创建一个副本并在副本上操作。
如果你非常坚定不想排序,那么有一种暴力解决方案(非常非常低效 - O(n^2)):
auto max = std::max_element(std::begin(v), std::end(v));
if (elem > *max) {
return elem;
}
auto i = elem;
while (std::find(std::begin(v), std::end(v), i) != std::end(v)) {
++i;
}
return i;