std::vectorすでにソートされていて、ペアの合計を計算することができ、その場では、あなたはO(1)スペースを持つベクトルのサイズの線形時間ソリューションを実現することができます。
以下は、追加のスペースを必要とせず、線形時間で実行されるSTLのような実装です。
template<typename BidirIt, typename T>
bool has_pair_sum(BidirIt first, BidirIt last, T sum) {
if (first == last)
return false; // empty range
for (--last; first != last;) {
if ((*first + *last) == sum)
return true; // pair found
if ((*first + *last) > sum)
--last; // decrease pair sum
else // (*first + *last) < sum (trichotomy)
++first; // increase pair sum
}
return false;
}
この考え方は、ベクトルを両端(正面と背面)から同時に反対方向にトラバースし、その間に要素のペアの合計を計算することです。
最初は、ペアはそれぞれ最小値と最大値を持つ要素で構成されています。結果の合計がより小さい場合sumは、前進firstします。イテレータは左端を指しています。それ以外の場合は、移動last–右端を指すイテレータ–逆方向。このようにして、結果の合計は徐々にに近づきsumます。両方のイテレータが同じ要素を指してしまい、合計が等しいペアsumが見つからない場合、そのようなペアはありません。
auto main() -> int {
std::vector<int> vec{1, 3, 4, 7, 11, 13, 17};
std::cout << has_pair_sum(vec.begin(), vec.end(), 2) << ' ';
std::cout << has_pair_sum(vec.begin(), vec.end(), 7) << ' ';
std::cout << has_pair_sum(vec.begin(), vec.end(), 19) << ' ';
std::cout << has_pair_sum(vec.begin(), vec.end(), 30) << '\n';
}
出力は次のとおりです。
0 1 0 1
関数テンプレートの一般的な性質のおかげで、has_pair_sum()双方向の反復子が必要なだけなので、このソリューションは次の場合にも機能しstd::listます。
std::list<int> lst{1, 3, 4, 7, 11, 13, 17};
has_pair_sum(lst.begin(), lst.end(), 2);