C++で配列内の各要素に最も近い大きい値を効率的に検索する方法
この記事では、配列内の各要素に対して「最も近い大きい値」を効率的に検索する方法を解説します。ある要素 x より大きい値が配列内に存在する場合、その中で最も小さい値(次に大きい要素)をその要素の答えとし、存在しない場合は -1 を出力します。
例として、配列が {10, 5, 11, 10, 20, 12} の場合、結果は {11, 10, 12, 11, -1, 20} となります。最大値の 20 より大きい要素は配列内に存在しないため、20 に対しては -1 が出力されます。
解決のアプローチ
この問題は C++ STL の set(セット)を使うと簡単に解決できます。set は二分探索木をベースに実装されており、要素は常にソートされた状態で保持されます。二分探索木では「中間順後続(inorder successor)」が必ず次に大きい要素に相当するため、upper_bound() 関数を利用すれば、各要素より大きい最小の要素を O(log n) の計算量で取得できます。
サンプルコード
#include<iostream>
#include<set>
using namespace std;
void nearestGreatest(int arr[], int n) {
set<int> tempSet;
for (int i = 0; i < n; i++)
tempSet.insert(arr[i]);
for (int i = 0; i < n; i++) {
auto next_greater = tempSet.upper_bound(arr[i]);
if (next_greater == tempSet.end())
cout << -1 << " ";
else
cout << *next_greater << " ";
}
}
int main() {
int arr[] = {10, 5, 11, 10, 20, 12};
int n = sizeof(arr) / sizeof(arr[0]);
nearestGreatest(arr, n);
}出力結果
11 10 12 11 -1 20
まず、すべての要素を set に挿入してソート済みの状態を作ります。その後、各要素に対して upper_bound() を呼び出すことで、その要素より大きい最小の要素を取得します。戻り値が end() イテレータと等しい場合は、それより大きい要素が存在しないことを意味するため、-1 を出力します。
このように set と upper_bound() を組み合わせることで、総当たり方式(O(n²))で探すよりもはるかに効率的に答えを求められます。全体の計算量は、要素の挿入と検索に O(n log n)、結果の出力に O(n) となります。
-
すべての要素がK以上になるまで配列の要素を追加するC++プログラム|最小ヒープによる効率的な解法
ソートされていない整数の配列 arr[] と整数 K が与えられたとき、配列内の2つの要素を選んで足し合わせて1つの要素にする操作を繰り返し、すべての要素を K 以上にするまでに必要な最小の操作回数を求めるのが本記事のテーマです。問題の例Input: arr[] = {1 10 12 9 2 3}, K = 6 Output: 2解説まず (1 + 2) を加算すると、新しい配列は 3 10 12 9 3 になります。次に (3 + 3) を加算すると、新しい配列は 6 10 12 9 となります。この時点で、リスト内のすべての要素が 6 以上になっていることが確認できます。したがって、答えは
-
C++で配列の全要素がK以上になるまで最小要素を加算する方法
配列(Array)とは、同じデータ型の要素を格納するコンテナであり、各要素は0から始まるインデックスで管理されます。この記事では、整数型の配列を扱い、配列内のすべての要素が指定された数値以上であるかどうかを確認します。具体的には、配列のすべての要素が与えられた数値 K 以上になっているかを判定し、条件を満たしていない場合は、配列内で最も小さい2つの要素を取り出して合計し、その合計値を1つの新しい要素として扱います。その後、再び同じ条件で新しい配列をチェックします。条件が満たされれば、加算を実行した回数を結果として返します。問題例Array = { 2, 6, 3, 12, 7 } K = 5