C++で2つの配列の共通部分(積集合)を求める方法
プログラミングでは、2つの配列が与えられたときに、両方に共通して含まれる要素(共通部分・積集合)を求めたい場面がよくあります。
例えば、入力が [1,5,3,6,9] と [2,8,9,6,7] の場合、両方の配列に存在する要素は 9 と 6 なので、出力は [9, 6] になります。
解決のアプローチ
この問題は、ハッシュマップ(unordered_map)を使って各配列の要素の出現回数を記録することで、効率的に解くことができます。手順は以下の通りです。
- 2つのマップ
mp1、mp2を定義します - 結果を格納するための配列
resを定義します nums1の各要素xについて、mp1[x]を1増やしますnums2の各要素xについて、mp2[x]を1増やしますmp1の各キーと値のペアxに対して以下を処理します- カウンタ
cntを0で初期化します cntに「xの値」と「mp2[x のキー]」のうち小さい方を代入しますcnt > 0である場合、つまり両方の配列にそのキーが存在する場合は、キーをresの末尾に追加します
- カウンタ
resを返します
この手法では、マップへの登録と参照が平均 O(1) で行えるため、配列の長さを n と m とすると、全体の計算量は O(n + m) となり、非常に効率的です。
実装例
それでは、実際のC++コードを見てみましょう。
#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v){
cout << "[";
for(int i = 0; i<v.size(); i++){
cout << v[i] << ", ";
}
cout << "]"<<endl;
}
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2){
unordered_map<int, int> mp1, mp2;
vector<int> res;
for (auto x : nums1)
mp1[x]++;
for (auto x : nums2)
mp2[x]++;
for (auto x : mp1) {
int cnt = 0;
cnt = min(x.second, mp2[x.first]);
if (cnt > 0)
res.push_back(x.first);
}
return res;
}
};
main(){
Solution ob;
vector<int> v = {1,5,3,6,9}, v1 = {2,8,9,6,7};
print_vector(ob.intersection(v, v1));
}
入力
{1,5,3,6,9},{2,8,9,6,7}
出力
[9, 6]
コードのポイント
unordered_map は要素の順序を保証しないため、出力結果の並び順(ここでは [9, 6])は実行環境によって変わる可能性があります。順序を整えたい場合は、結果をソートするか、map を使用するとよいでしょう。また、このアルゴリズムは重複する要素があっても正しく動作し、両方の配列に存在する要素だけを確実に抽出できます。
-
C/C++の多次元配列とは?基本概念から動的メモリ確保まで徹底解説
C/C++における多次元配列とは、簡単に言えば「配列の配列」として定義されるデータ構造です。多次元配列では、データが表形式(行優先順/row-major order)でメモリ上に格納されます。 以下の図は、3×3×3の次元を持つ多次元配列のメモリ割り当て戦略を示したものです。 アルゴリズム 2次元配列を動的に確保し、操作するための基本的な手順は以下の通りです。 Begin 配列の次元を宣言する new演算子を使用して2次元配列 a[][] を動的に確保する 配列に要素を格納する 配列の内容を出力する deleteによってメモリを解放する End サン
-
C++で2つの連結リストの交点を見つける方法
連結リストとは連結リスト(Linked List)は線形データ構造の一種です。各ノードは2つの部分で構成されており、一方にはノードの値(データ)が、もう一方には次のノードへのアドレス(ポインタ)が格納されています。ここでは、各ノードがリスト内の他のノードを指すポインタを持つ連結リストを想定します。この問題のタスクは、2つの連結リストが交差するノードを見つけることです。交差していない場合は、NULL(空)を出力として返します。入力例1出力:2解説: 与えられた連結リストは値「2」のノードで交差しているため、「2」を出力として返します。入力例2出力:NULL解説: 共通するノードが存在しないため、