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

C++で指定された合計値となるすべてのトリプレットを出力する方法

この問題では、重複のない整数の配列と合計値が与えられ、その合計値と等しくなる3つの要素の組み合わせ(トリプレット)をすべて見つける必要があります。

まず、具体例を使って問題を確認してみましょう。

入力 : array = {0 , 2 , -1 , 1, -2}
Sum = 1
出力 : 1 2 -2
0 2 -1

この問題を解くには、合計値に一致するすべてのトリプレットを見つけます。最もシンプルなアプローチは、3重ループを使ってすべての要素の組み合わせの合計を計算し、条件に合致するトリプレットを出力する方法です。

方法1:3重ループによる全探索

#include <iostream>
using namespace std;
void Triplets(int arr[], int n, int sum){
    for (int i = 0; i < n - 2; i++) {
        for (int j = i + 1; j < n - 1; j++) {
            for (int k = j + 1; k < n; k++) {
                if (arr[i] + arr[j] + arr[k] == sum) {
                    cout<<arr[i]<<"\t"<<arr[j]<<"\t"<<arr[k]<<endl;
                }
            }
        }
    }
}
// ドライバーコード
int main(){
    int arr[] = { 0 , 2 , -1 , 1, -2 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout<<"The Triplets are : \n";
    Triplets(arr, n, 1);
    return 0;
}

出力

The Triplets are :
0 2 -1
2 1 -2

しかし、このアプローチでは3重ループを実行するため、時間計算量がO(n3)となり、大規模な配列に対しては非効率です。そこで、より効果的な手法を用いてこの問題を解決します。

その一つがハッシュ(unordered_set)を活用する方法です。この方法では、各要素について、残りの2つの要素の合計が補完関係になるペアを探します。具体的には、値xを持つ要素に対して、sum − x に相当する要素がすでに存在するかをハッシュセットで高速に判定します。

これにより、コードの時間計算量をO(n2)まで削減できます。

方法2:ハッシュを使用した効率的な解法

#include <bits/stdc++.h>
using namespace std;
void Triplets(int arr[], int n, int sum){
    for (int i = 0; i < n - 1; i++) {
        unordered_set<int> triplet;
        for (int j = i + 1; j < n; j++) {
            int third = sum - (arr[i] + arr[j]);
            if (triplet.find(third) != triplet.end())
                cout<<third<<"\t"<<arr[i]<<"\t"<<arr[j]<<endl;
            else
                triplet.insert(arr[j]);
        }
    }
}
int main(){
    int arr[] = { 0 , 2 , -1 , 1, -2 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout<<"The Triplets are : \n";
    Triplets(arr, n, 1);
    return 0;
}

出力

The Triplets are :
0 2 -1
2 1 -2

さらに、配列を事前にソートすることで、この方法の空間計算量を削減し、より効率的にすることができます。ソート後は two-pointer(双方向ポインタ)テクニックを組み合わせることで、追加のメモリを使用せずに解くことも可能です。

  1. C++で始点から終点までのすべての経路を出力する方法|深さ優先探索(DFS)による実装

    この記事では、有向グラフが与えられたときに、始点(ソース)から終点(デスティネーション)までのすべての経路を出力する問題を、C++で解く方法を解説します。有向グラフとは?有向グラフとは、各辺に向きが定められており、頂点Aから頂点Bへと一方向に進むことができるグラフのことです。逆向き(BからA)には、対応する逆向きの辺が存在しない限り移動できません。問題の例具体例を使って問題を理解しましょう。下図のようなグラフを考えます。始点を「K」、終点を「P」とした場合の出力は次のようになります。出力:K -> T -> Y -> A -> P K -> T -> Y -

  2. C++で指定された合計値となるすべての一意なトリプレットを見つける方法

    今回は、配列の中から3つの要素を選び、その合計が指定された値と一致する「トリプレット(三つ組)」をすべて見つけるという、興味深い問題を解説します。問題の概要いくつかの要素を含む配列と、目標となる合計値が与えられます。この中から合計が指定値と等しくなる3つの要素の組み合わせをすべて抽出するのがタスクです。例えば、配列が {4, 8, 63, 21, 24, 3, 6, 1, 0} で、合計値 S = 27 が与えられた場合、条件を満たすトリプレットは {0, 3, 24}、{0, 6, 21}、{1, 5, 21} となります。条件を満たす組み合わせが複数存在する場合は、それらをすべて出力します