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);