如果将数组放入子范围然后对这些子范围进行排序,则可以解决问题。让我们详细看看,
给定数组 = [10, 12, 8, 17, 3, 24, 19]
现在将数组划分为长度为4 的子范围,并对这些子范围进行排序,如下所示,
子范围排序数组
.................... ...............
| 8 | 10 | 12 | 17 | | 3 | 19 | 24 |
.................... ...............
2 0 1 3 4 6 5 => index
让我们获取子范围排序数组的第一个条目8,并尝试找到大于8的右元素数
正如您在上面的数字8 中看到的那样,属于第一个子范围,并且由于子范围已排序,子范围中的元素按升序排列,但不按索引顺序排列。这意味着在当前子范围内,我们必须将元素8右侧的所有元素的索引与元素8的索引进行比较
8 的索引是2 但10 有index = 0,这意味着10 在输入数组中位于8 的左侧,
12 的索引也小于8 的索引,这意味着12 在输入数组中位于8 的左侧,
17 的索引是3 大于8 的索引,这意味着17 在输入数组中位于8 的右侧,可以认为是更大的元素,
在将8的索引与当前子范围所有右元素的索引进行比较后,右更大的元素count = 1,让我们看看下一个范围,
在8的子范围之后,事情完全改变了,现在我们知道这个子范围在子范围元素8所属的右边,这意味着我们不必比较8的索引有元素或这个范围,都在元素8的右边,我们只需要找到大于8的数量,
现在我们将右子范围的第一个元素与8 进行比较,正如您在上面看到的,第一个元素是3,它小于8,但如果右子范围的第一个元素大于当前元素然后我们可以直接将 count 增加到右子范围中存在的元素数。
因为第一个元素3 小于8,我们在右子范围内找到8 的上限,即19,并且右子范围内19 中的所有元素都大于@987654359 @,所以有两个元素19, 24,由于这个计数增加了two,变成count = 3
最后有3右元素大于元素8。
以类似的方式,可以为所有元素找到更大的右元素数量,结果数组将是,
x(A) = [4, 3, 3, 2, 2, 0, 0]
结论是,通过将输入数组划分为已排序的子范围,可以通过以下步骤找到右侧更大的元素,
- 比较当前子范围所有正确元素的索引,
- 比较右子范围的第一个元素和如果,
一世。第一个元素大于当前元素,而不是右侧范围内的所有元素都大于当前元素,
ii.第一个元素小于,然后找到右子范围内当前元素的上界,右子范围内上界的元素大于当前元素。
- 对所有正确的子范围重复第 2 步。
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
using std::cout;
std::vector<std::pair<int, std::size_t>> arrayOfSortedSubRange(std::size_t subRangeSize,
const std::vector<int>& numArr){
std::vector<std::pair<int, std::size_t>> res;
res.reserve(numArr.size());
for(std::size_t i = 0, numArrSize = numArr.size(); i < numArrSize; ++i){
res.emplace_back(numArr[i], i);
}
for(std::vector<std::pair<int, std::size_t>>::iterator it = res.begin(), endIt = res.end(); endIt != it;){
std::vector<std::pair<int, std::size_t>>::iterator rangeEndIt = it + std::min<std::ptrdiff_t>(endIt - it,
subRangeSize);
std::sort(it, rangeEndIt, [](const std::pair<int, std::size_t>& a, const std::pair<int, std::size_t>& b){
return a.first < b.first;});
it = rangeEndIt;
}
return res;
}
std::size_t rightGreterElmentCountOfNumber(int num, std::vector<std::pair<int, std::size_t>>::const_iterator rightSubRangeIt,
std::vector<std::pair<int, std::size_t>>::const_iterator endIt){
std::size_t count = 0;
std::vector<std::pair<int, std::size_t>>::const_iterator subRangEndIt = rightSubRangeIt +
std::min<std::ptrdiff_t>(endIt - rightSubRangeIt, 4);
while(endIt != rightSubRangeIt){
if(rightSubRangeIt->first > num){
count += subRangEndIt - rightSubRangeIt;
}
else{
count += subRangEndIt -
std::upper_bound(rightSubRangeIt, subRangEndIt, num, [](int num,
const std::pair<int, std::size_t>& element){ return num < element.first;});
}
rightSubRangeIt = subRangEndIt;
subRangEndIt += std::min<std::ptrdiff_t>(endIt - subRangEndIt, 4);
}
return count;
}
std::vector<std::size_t> rightGreaterElementCountForLessThanFiveNumbers(const std::vector<int>& numArr){
std::vector<std::size_t> res(numArr.size(), 0);
std::vector<std::size_t>::iterator resIt = res.begin();
for(std::vector<int>::const_iterator it = numArr.cbegin(), lastIt = it + (numArr.size() - 1); lastIt != it;
++it, ++resIt){
*resIt = std::count_if(it + 1, numArr.cend(), [num = *it](int rightNum){return rightNum > num;});
}
return res;
}
std::vector<std::size_t> rightGreaterElementCount(const std::vector<int>& numArr){
if(numArr.size() < 5){
return rightGreaterElementCountForLessThanFiveNumbers(numArr);
}
std::vector<std::size_t> resArr(numArr.size(), 0);
std::vector<std::pair<int, std::size_t>> subRangeSortedArr = arrayOfSortedSubRange(4, numArr);
for(std::vector<std::pair<int, std::size_t>>::const_iterator it = subRangeSortedArr.cbegin(),
endIt = subRangeSortedArr.cend(); endIt != it;){
std::vector<std::pair<int, std::size_t>>::const_iterator rightNextSubRangeIt = it + std::min<std::ptrdiff_t>(
endIt - it, 4);
for(std::vector<std::pair<int, std::size_t>>::const_iterator eleIt = it; rightNextSubRangeIt != eleIt; ++eleIt){
std::size_t count = std::count_if(eleIt, rightNextSubRangeIt, [index = eleIt->second](
const std::pair<int, std::size_t>& element){ return index < element.second;});
if(endIt != rightNextSubRangeIt){
count += rightGreterElmentCountOfNumber(eleIt->first, rightNextSubRangeIt, endIt);
}
resArr[eleIt->second] = count;
}
it += std::min<std::ptrdiff_t>(endIt - it, 4);
}
return resArr;
}
int main(){
std::vector<std::size_t> res = rightGreaterElementCount({10, 12, 8, 17, 3, 24, 19});
cout<< "[10, 12, 8, 17, 3, 24, 19] => [";
std::copy(res.cbegin(), res.cbegin() + (res.size() - 1), std::ostream_iterator<std::size_t>(cout, ", "));
cout<< res.back()<< "]\n";
}
输出:
[10, 12, 8, 17, 3, 24, 19] => [4, 3, 3, 2, 2, 0, 0]