1. [1,2,3] -> [3,2,1]
  2. [10] -> [10]
  3. [1,2,3,4,5] -> [5,4,3,2,1]
  4. [7,8] -> [8,7]
  5. [1,1,2,2] -> [2,2,1,1]
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
リンクリストの反転

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

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

リンクリストの反転

ブラウザの履歴は、今いるページから 1 つ前へ、また 1 つ前へとたどれるようにつないであります。これを逆側からたどれる形に作り替えるのが反転です。札の向きを 1 本ずつ裏返していきます。

裏返した瞬間、次がどこか分からなくなる

先頭から順に、next を 1 つ前のノードへ向け直していけばよさそうに見えます。ところが素直に書くと、2 個目で止まります。

Python

prev = None cur = head while cur is not None: cur.next = prev # ここで元の行き先が消える prev = cur cur = cur.next # もう prev を指している

cur.next を書き換えた時点で、元々の行き先を書いた札は上書きされています。次の行で cur.next を読んでも、返ってくるのは今しがた自分で書いた prev です。1 歩も先へ進めないまま、来た道を戻ることになります。

上書きする前に、行き先を手に持っておく

必要なのは 3 つ目の変数です。裏返す前に、元の行き先をそこへ退避します。

Python

prev = None cur = head while cur is not None: nxt = cur.next # 逃がす cur.next = prev # 裏返す prev = cur # 2 つそろって 1 歩進む cur = nxt

逃がす、裏返す、進む。この順番が命です。prev cur nxt の 3 つを持つ理由は、裏返す一手で片方の情報が必ず消えるからにほかなりません。消える前に手に持っておく、それだけのために 3 つ目がいます。

1 -> 2 -> 3 の 1 周目を追ってみます。nxt が 2 を受け取り、1 の札が空を向き、prev が 1、cur が 2 へ移ります。2 周目で 2 の札が 1 を向きます。鎖が一度にひっくり返るのではなく、前から 1 本ずつ向きが変わっていく様子が見えるはずです。

JavaScript でも変わりません。

JavaScript

let prev = null; let cur = head; while (cur !== null) { const nxt = cur.next; cur.next = prev; prev = cur; cur = nxt; }

なお、prev の初期値が空なのも意味があります。元の先頭は反転後の末尾になるので、その next は空でなければなりません。最初の 1 回で cur.next = None が入り、末尾の印がそこに置かれます。

返すのは cur ではなく prev

ループを抜けたとき cur は空です。末尾の 1 つ先まで来ているからです。新しい先頭は、最後に裏返したノード、つまり prev の側に残っています。ここを取り違えると、戻り値が空になって「なぜか何も返ってこない」という状態になります。

裏返し終わるまで、元の並びをたどる手段は 1 つも残りません。だから途中で状態を確かめたいときは、反転の前に値を控えておく必要があります。

今回の課題は配列で同じことをします。札が無いぶん変数 3 つは要りませんが、順序を 1 か所ずつ入れ替えていく感覚は変わりません。手を動かす前に、3 要素の列を紙に書いて、どこから何を動かすと壊れないかを追ってみてください。

要件

  1. 連結リストは配列 arr で表現する
  2. 戻り値は反転した新しい配列
  3. 元の配列を破壊的に変更しても良いが、戻り値が反転していること

入出力例

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

ヒント

result.insert(0, value) や result.unshift(value) で先頭に追加すると自然に反転する

arr[::-1] や arr.slice().reverse() でも書けるが、アルゴリズムを理解するために手書きで書こう

空配列を入れたら空配列が返るように、初期化を [] / new int[0] にしておく

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

関連レッスン

  • リンクリストのサイクル検出

    Floyd の Tortoise and Hare アルゴリズムを使って連結リストのサイクル有無を判定する。

  • ソート済みリンクリストの merge

    ソート済みの 2 つの連結リストを 1 つにマージし、merge sort の核となる手法を理解する。

  • リンクリストの中央ノード取得

    slow / fast の 2 ポインタ法を使って連結リストの中央ノードの値を一発で取得する。

  • ソート済みリストの重複削除

    ソート済み連結リストから連続する重複ノードを除去し、in-place な編集の発想を身につける。

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

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

  • ブラウザユーザーから見たWebのクライアント
  • 変数データに名前をつけて参照する仕組み
  • JavaScriptWeb で動的な振る舞いを担う言語
  • ループ繰り返し処理。矢印で戻すか専用記号で示す
  • 戻り値呼び出し元への返答を表す点線矢印
  • 配列サイズ固定の同型データの集まり
  • 連結リスト各要素が次の要素へのポインタを持つ構造。
  • リスト順序付きで複数の値を扱うデータ構造
main.py
学習モード
エディタを読み込んでいます

メモ

リンクリストの反転

⌘S で保存