1. [3,1,2,4] -> [[2,4],[1,3]]
  2. [1,2,3,4,5] -> [[2,4],[1,3,5]]
  3. [2,4,6] -> [[2,4,6],[]]
  4. [1,3,5] -> [[],[1,3,5]]
  5. [10,7,8,3,1] -> [[8,10],[1,3,7]]
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
キーでグループ化

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

探索、ソート、木、グラフ、動的計画法、貪欲法など、競技プログラミングや技術面接で問われる高度なアルゴリズムとデータ構造を学べるコースです。基本的な 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分

キーでグループ化

分け先が 5 つになったら、5 周する気ですか

偶数だけを集めて 1 周、奇数だけを集めてもう 1 周。2 つならまだ我慢できます。しかし「3 で割った余りで分けろ」と言われた瞬間に 3 周、月ごとに分けろと言われたら 12 周です。

分け先がいくつに増えても、配列を読む回数は 1 回で足ります。

入れ物は、出てきたときに作る

JavaScript

// 別題材 — 商品をカテゴリごとに束ねる const groups = {}; for (const item of items) { const key = item.category; if (!groups[key]) groups[key] = []; groups[key].push(item.name); }

肝は if (!groups[key]) groups[key] = [] の 1 行です。キーがまだ無いところに push しようとしても、押し込む相手がいません。先に空の入れ物を置いてから入れます。数えるときの「無ければ 0 から」と同じ形で、こちらは「無ければ空の入れ物から」です。

こうすれば、分け先がいくつあっても配列を歩くのは 1 周だけになります。

今回の課題は分け先が 2 つと決まっているので、キー付きの表を用意せず、入れ物を 2 つ並べても構いません。表を使うかどうかが目的ではなく、1 周で振り分けきることが目的です。

中身は合っているのに落ちる

今回の課題で落ちる原因の大半は、値ではなく並びです。振り分けた順のまま返すと、[3, 1, 2, 4] から [[2, 4], [3, 1]] が出てきます。中身は正しいのに、奇数側が昇順になっていません。返す前に必ず並べ替えます。

JavaScript で並べ替えるときは、比べ方を渡してください。

JavaScript

[10, 2, 1].sort(); // [1, 10, 2] — 文字列として比べている [10, 2, 1].sort((a, b) => a - b); // [1, 2, 10]

既定の sort は、要素を文字列に直してから並べます。"10" は "2" より前に来るので、数の大小とは違う結果になります。1 桁の数しか無いテストでは気づけないのが、この罠の嫌なところです。

負の数の余りは言語で違う

偶数と奇数の振り分けにも 1 つ落とし穴があります。

  • Python の -3 % 2 は 1
  • JavaScript の -3 % 2 は -1

余りが 1 なら奇数 と書くと、JavaScript では -3 が奇数から漏れて、どちらのグループにも入らなくなります。余りが 0 なら偶数、そうでなければ奇数 と、判定を 1 つだけ書いて残りをまとめるほうが安全です。

解説

空の配列を渡されても、返す形は変わりません。中身が空の入れ物を 2 つ入れて返します。

要件

  1. 戻り値は [偶数の昇順リスト, 奇数の昇順リスト] の 2 要素配列
  2. 1 パスでグループに振り分けてから昇順ソートする (O(n log n))
  3. 空配列は [[], []] を返す

入出力例

groupByParity([3,1,2,4]) → [[2,4],[1,3]] groupByParity([1,2,3,4,5]) → [[2,4],[1,3,5]] groupByParity([2,4,6]) → [[2,4,6],[]] groupByParity([1,3,5]) → [[],[1,3,5]] groupByParity([10,7,8,3,1]) → [[8,10],[1,3,7]]

ヒント

偶奇判定は `v % 2 == 0` を使う (JS / Java / Go で負の数の `%` が異なるため `== 1` 判定は避ける)

JavaScript の `Array.prototype.sort()` は文字列比較がデフォルト。必ず `(a, b) => a - b` を渡す

Java では `List<Integer>` で集めてから `int[]` に詰め直すと書きやすい

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

関連レッスン

  • two sum (hash で O(n))

    整数配列と目標値 `target` を受け取り、和が `target` になる 2 要素のインデックスをソート済みリストで返す。

  • 部分配列の和 = k の個数

    整数配列と `k` を受け取り、和が `k` になる **連続する部分配列** の個数を `hashmap` と累積和で `O(n)` で数える。

  • 最長連続部分列

    整数配列を `set` に入れて、連続する整数で最も長いシーケンスの長さを `O(n)` で求める。

  • 集合の積 (intersection)

    2 つの整数配列の共通要素 (集合の積) を `set` で求めて、重複なしの昇順リストで返す。

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

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

  • 配列サイズ固定の同型データの集まり
  • JavaScriptWeb で動的な振る舞いを担う言語
  • テストバグを見つける工程
  • ループ繰り返し処理。矢印で戻すか専用記号で示す
  • 戻り値呼び出し元への返答を表す点線矢印
main.py
学習モード
エディタを読み込んでいます

メモ

キーでグループ化

⌘S で保存