这个问题可以通过创建一个包含数字及其索引的数组来解决,如下所示,
原始数组 = [9, 2, 3, 4, 0, 4, 5, 6, 0, 8],
数字索引数组 = [9, 0], [2, 1], [3, 2], [4, 3], [0, 4], [4, 5 ], [5, 6], [6, 7], [0, 8], [8, 9]
这里std::pair 的第一个元素是数字本身,第二个元素是数字的索引。
之后,将此数组按数字排序,结果如下,
[0, 8], [0, 4], [2, 1], [3, 2], [4, 5], [4, 3], [@ 987654339@, 6], [6, 7], [8, 9], [9, 0]
排序的目的是使相同的数字彼此相邻。一旦相同的数字相邻,就需要简单的迭代来找到答案。让我们看看它是如何工作的,
排序数组中的第一个数字是0,通过找到0 的upper bound 将给出所有相邻的0,这意味着以下将可用,
[0, 8], [0, 4]
但是正如您在上面看到的,这些条目不是按照索引4 的索引条目的顺序排列在索引8 的条目之后,这是因为std::sort 不是一个稳定的排序,这意味着元素的相对顺序不会被保留.所以在继续之前,这些元素必须再次按索引排序,结果将是
[0, 4], [0, 8]
如上所示索引4和8不相邻4 + 1 != 8,非相邻数字的计数为two。
检查0 的所有条目,算法将考虑下一个数字2,但正如您在上面看到的数组中只有一个数字2 的条目[2, 1] 并且由于这个下一个数字将考虑一下,所有号码都会发生同样的情况,所以让我们直接查看号码4,它有多个条目,如下所示,
[4, 5], [4, 3]
然后按索引对这些条目进行排序,
[4, 3], [4, 5]
这里再次索引不是相邻索引3 + 1 != 5,非相邻数的计数是two。相同的过程将应用于所有数字,最终答案将是最大非相邻数字count = 2
对于数组[4, 4, 4, 4, 4]的其他示例,它的最终编号和索引数组将是,
[4, 0], [4, 1], [4, 2], [4, 3], [4, 4]
如您所见,索引0、2、4 不是相邻索引和最大非相邻数count = 3
#include <iostream>
#include <vector>
#include <algorithm>
using std::cout;
std::size_t countNonAdjacentEntries(std::vector<std::pair<int, std::size_t>>::const_iterator firstIt,
std::vector<std::pair<int, std::size_t>>::const_iterator lastIt){
std::size_t count = 0;
for(std::vector<std::pair<int, std::size_t>>::const_iterator preIt = firstIt, it = preIt + 1; lastIt != it;){
if(preIt->second + 1 != it->second){
++count;
preIt = it;
++it;
}
else{
++it;
}
}
++count;
return count;
}
std::size_t maxNonAdjacentNumber(const std::vector<int>& numbers){
std::vector<std::pair<int, std::size_t>> numAndIndex;
numAndIndex.reserve(numbers.size());
for(std::vector<int>::size_type i = 0, numbersCount = numbers.size(); i < numbersCount; ++i){
numAndIndex.emplace_back(numbers[i], i);
}
std::sort(numAndIndex.begin(), numAndIndex.end(),
[](const std::pair<int, std::size_t>& a, const std::pair<int, std::size_t>& b){
return a.first < b.first;});
std::size_t count = 0;
for(std::vector<std::pair<int, std::size_t>>::const_iterator it = numAndIndex.cbegin(), endIt = numAndIndex.cend();
endIt != it; ){
std::vector<std::pair<int, std::size_t>>::const_iterator upBoundIt = std::upper_bound( it + 1, endIt, it->first,
[](int val, const std::pair<int, std::size_t>& ele){return val < ele.first;});
if(upBoundIt - it > 1){
std::sort(numAndIndex.begin(), numAndIndex.end(),
[](const std::pair<int, std::size_t>& a, const std::pair<int, std::size_t>& b){
return a.second < b.second;});
count = std::max(count, countNonAdjacentEntries(it, upBoundIt));
it = upBoundIt;
}
else{
++it;
}
}
return count;
}
int main(){
cout<< "[9, 2, 3, 4, 0, 4, 5, 6, 0, 8] => "<< maxNonAdjacentNumber({9, 2, 3, 4, 0, 4, 5, 6, 0, 8})<< '\n';
cout<< "[4, 4, 4, 4, 4] => "<< maxNonAdjacentNumber({4, 4, 4, 4, 4})<< '\n';
}
输出
[9, 2, 3, 4, 0, 4, 5, 6, 0, 8] => 2
[4, 4, 4, 4, 4] => 3