C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で2つの配列から作れるペアの最大数を求めるアルゴリズム

問題の概要

同じサイズ N を持つ2つの配列が与えられたとき、各配列から1つずつ要素を選んでペアを作り、そのペアの最大数を求めます。ただし、以下の条件を満たす必要があります。

  • 各配列の要素は最大1回しか使用できない
  • ペアを構成する2つの要素の絶対差が指定された値 K 以下であること

入力例

たとえば、次のような入力が与えられたとします。

arr1[] = {3, 4, 5, 2, 1}
arr2[] = {6, 5, 4, 7, 15}
k = 3

この場合、絶対差が3以下になるペアは次の4組です。

(1, 4), (2, 5), (3, 6), (4, 7)

したがって、答えは 4 となります。

アルゴリズムの考え方

この問題は、貪欲法(グリーディー法)に基づくシンプルな反復処理で解くことができます。

  1. 両方の配列を昇順にソートする — 小さい要素同士から順にマッチングを試みることで、効率よくペアを見つけられます。
  2. 第1配列の各要素について、第2配列の未使用要素と比較する — 絶対差が K 以下であればペアとして成立します。
  3. ペアが成立したら、使用済みフラグを立てて次へ進む — 各要素は1回しか使えないため、bool 型の配列で使用状況を管理します。

C++での実装例

それでは、実際のコードを見てみましょう。

#include <bits/stdc++.h>
using namespace std;

int getMaxUniquePairs(int *arr1, int *arr2, int n, int k) {
    sort(arr1, arr1 + n);
    sort(arr2, arr2 + n);

    bool visited[n];
    memset(visited, false, sizeof(visited));

    int pairCnt = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if (abs(arr1[i] - arr2[j]) <= k &&
                visited[j] == false) {
                ++pairCnt;
                visited[j] = true;
                break;
            }
        }
    }
    return pairCnt;
}

int main() {
    int arr1[] = {3, 4, 5, 2, 1};
    int arr2[] = {6, 5, 4, 7, 15};
    int n = sizeof(arr1) / sizeof(arr1[0]);
    int k = 3;

    cout << "Maximum unique pairs = "
         << getMaxUniquePairs(arr1, arr2, n, k) << endl;
    return 0;
}

実行結果

Maximum unique pairs = 4

計算量について

この実装では二重ループを使用しているため、時間計算量は O(N²) となります。N が大きい場合は、ソート後に両配列を先頭から順に走査し、条件を満たす要素までポインタを進めていく「二ポインタ(two-pointer)」手法を使うことで、O(N log N)(ソート込み)まで高速化できます。

まとめ

2つの配列から絶対差 K 以下のペアを最大化する問題は、ソートと貪欲なマッチングを組み合わせることで簡潔に解決できます。要素の再利用を防ぐために visited フラグで管理する点がポイントです。より大規模な入力に対応したい場合は、二ポインタ方式への置き換えも検討してみてください。

  1. C++でソート済みの2つの配列からxに最も近い合計値を持つペアを見つける方法

    ソート済みの2つの配列と数値 x が与えられたとき、合計が x に最も近くなるペアを見つける必要があります。このペアは、それぞれの配列から1つずつの要素を組み合わせたものです。具体的には、配列 A1[0..m-1] と A2[0..n-1]、および目標値 x が与えられ、|A1[i] + A2[j] − x| の絶対値が最小となるような A1[i] + A2[j] の組み合わせを求めます。例えば、A1 = [1, 4, 5, 7]、A2 = [10, 20, 30, 40]、x = 32 の場合、出力は「1 と 30」になります(1 + 30 = 31 が x = 32 に最も近いため)。アル

  2. C++で2つのソート済み配列をマージする方法|効率的なアルゴリズムと実装例

    問題の概要ソート済みの2つの配列が与えられたとき、それらを1つのソート済み配列へマージ(統合)する関数を作成します。これはマージソートの中核となる処理であり、技術面接や競技プログラミングでも頻出のテーマです。Arr1[] = {10, 15, 17, 20} Arr2[] = {5, 9, 13, 19} Result[] = {5, 9, 10, 13, 15, 17, 19, 20}アプローチのポイント単純に2つの配列を連結してから再ソートすることも可能ですが、それぞれがすでにソート済みであるという性質を活かせば、ツーポインタ(2つのインデックス)手法によって O(n1 + n2) の計算