1. a=[1,2,2,3], b=[2,3,4] -> [2,3]
  2. a=[1,5,3], b=[7,3,5,1] -> [1,3,5]
  3. a=[1,2,3], b=[4,5,6] -> []
  4. a=[10,9,8,7], b=[8,9] -> [8,9]
  5. a=[-3,-1,0,2], b=[2,0,-1,-5] -> [-1,0,2]
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
集合の積 (intersection)

コンピューターサイエンス上級:アルゴリズムとデータ構造

探索、ソート、木、グラフ、動的計画法、貪欲法など、競技プログラミングや技術面接で問われる高度なアルゴリズムとデータ構造を学べるコースです。基本的な CS の知識を持ち、アルゴリズム力を伸ばしたい学習者や、外資・大手の技術面接対策をしたい方を対象としています。約 13 時間 (1 日 30 分 × 26 日) で 50 レッスンを修了でき、修了後はコーディング面接の実装問題を構造的に解けるようになります。

1
連結リスト
01. リンクリスト構築と長さの計算5分
02. リンクリストの反転5分
03. リンクリストのサイクル検出5分
04. ソート済みリンクリストの merge5分
05. リンクリストの中央ノード取得5分
06. ソート済みリストの重複削除5分
07. 第1章まとめクイズ5分
2
二分木
01. 二分木の in-order 走査5分
02. 二分木の pre-order 走査5分
03. 二分木の post-order 走査5分
04. 二分木の幅優先走査 (BFS)5分
05. 二分木の高さ5分
06. 二分木の平衡判定5分
07. 第2章まとめクイズ — 二分木5分
3
探索木 (BST)
01. BST に値を挿入する5分
02. BST から値を検索する5分
03. BST の最小値と最大値5分
04. BST 妥当性チェック5分
05. BST で k 番目に小さい値5分
06. BST から値を削除する5分
07. 第 3 章 まとめクイズ5分
4
ハッシュとセット
01. hashmap で頻度集計5分
02. キーでグループ化5分
03. two sum (hash で O(n))5分
04. 部分配列の和 = k の個数5分
05. 最長連続部分列5分
06. 集合の積 (intersection)5分
07. 第4章まとめクイズ5分
5
グラフ
01. グラフ BFS で連結成分サイズを求める5分
02. グラフ DFS で連結成分の数を数える5分
03. グラフのパス存在判定5分
04. BFS で最短経路の長さを求める5分
05. トポロジカルソート5分
06. 2 部グラフ判定5分
07. ダイクストラ法 — 重み付きグラフの最短経路15分
08. 第5章まとめクイズ — グラフ5分
6
動的計画法 (上級)
01. 編集距離 (レーベンシュタイン距離)5分
02. 最長増加部分列(LIS)の解法 ── AOJ 2430 対応の動的計画法5分
03. 最大部分配列和 (Kadane)5分
04. 隣り合わない最大値 (House Robber)5分
05. グリッド経路数 (Unique Paths)5分
06. 単語分割可能か (Word Break)5分
07. 第6章まとめクイズ — 動的計画法 (上級)5分
7
総合データ構造と関数型
01. map と filter を組み合わせる5分
02. reduce で積を計算5分
03. 関数合成5分
04. カリー化5分
05. trie の単純検索 (prefix マッチ)5分
06. Union-Find (連結成分数)5分
07. 最終総まとめクイズ5分

集合の積 (intersection)

3000 件と 5000 件を突き合わせて 1500 万回

2 つの配列の両方に入っている値を集めます。素直に書けば、片方から値を 1 つ取り、もう片方に入っているかを見に行く形です。

問題は、その「入っているか」を配列に聞いていることです。配列は端から順に見るので、1 回聞くのに相手の件数ぶんかかります。3000 件と 5000 件なら 1500 万回。しかも、すでに拾った値かどうかを結果の配列に聞き直していると、その上にもう一段乗ります。

片方だけを、聞ける形に変える

両方を変える必要はありません。片方を先に集合にしておき、もう片方を 1 周するだけで済みます。

Python

# 別題材 — 出席者に入っているかを聞く attendees = set(attendee_list) # 作るのは 1 回だけ for name in applicants: if name in attendees: ...

集合を作るのに 3000 回、回すのに 5000 回。合わせて 8000 回まで落ちました。1500 万回との差は、聞き方を変えただけで生まれています。ループの数が減ったわけではありません。回すのは 1 周のままで、その中で聞く相手を配列から集合に替えただけです。

厄介なのは、この差がコードの見た目に出ないことです。Python の x in b は、b がリストなら端から探し、集合なら一発で返します。書いてある 2 文字は同じなのに速さがまるで違うので、聞いている相手が何なのかを毎回意識してください。

どちらを集合にするかは選べます。件数が少ないほうを集合にすれば、抱えておく量が減ります。ただし、回すほうを取り違えないでください。集合にした側を回してしまうと、聞く相手が配列に戻り、元の遅さに逆戻りします。

同じ値が 2 回出てくる

a = [1, 2, 2, 3] と b = [2, 3, 4] を突き合わせると、a の 2 が 2 つとも引っかかります。結果に素直に足していくと [2, 2, 3] になり、テストは落ちます。

拾った値を入れる側も、重複を持てない入れ物にしておけば、これは何もせずに消えます。「もう拾ったか」を毎回確かめる条件を書き足す必要はありません。片方を集合にした時点で b 側の重複も消えているので、両側に重複があっても大丈夫です。

出てくる順は約束されていない

最後に並べ替えます。集合から値を取り出す順は、入れた順とも小さい順とも限りません。言語や実装によって違いますし、同じ言語でも中身が変われば変わります。

手元で偶然そろっていると気づけないので、返す前に必ず昇順にしてください。[-3, -1, 0, 2] と [2, 0, -1, -5] のように負の数が混ざる場合も同じです。並べ替えたときに、負の数が正しく前へ来ているかを確かめてください。

共通する値が 1 つも無いときは、空の配列を返します。何も見つからなかったことを null で表すと、呼ぶ側の場合分けが増えます。

要件

  1. 戻り値は重複なし、かつ昇順ソート済みのリスト
  2. set を使って O(n + m) で実装する (二重ループ O(n*m) は避ける)
  3. 共通要素がない場合は空のリスト [] を返す

入出力例

setIntersection([1,2,2,3], [2,3,4]) → [2,3] setIntersection([1,5,3], [7,3,5,1]) → [1,3,5] setIntersection([1,2,3], [4,5,6]) → [] setIntersection([10,9,8,7], [8,9]) → [8,9] setIntersection([-3,-1,0,2], [2,0,-1,-5]) → [-1,0,2]

ヒント

片方を `set` に入れて、もう片方を走査しながら `set` のメンバーシップ判定をする

結果は `set` で集めると自動で重複が消える。最後に `sorted` / `Arrays.sort` で昇順にする

Java は `TreeSet` を使えばソート済みで取り出せる。Go は `sort.Ints` を使う

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • 第4章まとめクイズ

    ハッシュとセットの計算量・性質・使いどころを 4 択クイズで総点検する。

  • グラフ BFS で連結成分サイズを求める

    幅優先探索 (BFS) を使って、指定した頂点を含む連結成分のノード数を返す関数を実装する。

  • 編集距離 (レーベンシュタイン距離)

    2 つの文字列を一致させるために必要な最小編集回数を、二次元 DP で求める古典問題に挑戦します。

  • map と filter を組み合わせる

    配列に対して `map` と `filter` を組み合わせ、偶数だけを 2 倍した結果を返す関数を実装する。関数型プログラミングの基礎を学ぶ。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • 配列サイズ固定の同型データの集まり
  • ループ繰り返し処理。矢印で戻すか専用記号で示す
  • リスト順序付きで複数の値を扱うデータ構造
  • テストバグを見つける工程
  • 戻り値呼び出し元への返答を表す点線矢印
main.py
学習モード
エディタを読み込んでいます

メモ

集合の積 (intersection)

⌘S で保存