問題
連結リストのhead を
- 各節は
val(値) とnext(次の節) を 持ちます。 最後の 節の nextは、Python では None、JavaScript では null、Go では nilです。Go の 節は ListNodeで、Val、Nextと大文字で 始まります - 新しい
節は 作らず、 今ある 節の つなぎ先を 付け替えて 逆に してください - リストが
空 ( headが無い ) の ときは、 空のまま返します - 節の
数は 0 以上 5000 以下、 値は どれも -5000 以上 5000 以下です
例では、
入力と出力の例
例 1
入力
head = [3, 8, 1, 5]出力
[5, 1, 8, 3]例 2
節が 1 つなら、
入力
head = [9]出力
[9]例 3
空の
入力
head = []出力
[]面接での聞かれ方
連結リストの
- 「単方向の
連結リストを 逆順に してください」 - 書き終えた
あとに 「再帰でも書けますか?」と 聞かれる ことが 多いです。 書ける ことに 加えて、 深いリストで 再帰の 段が 増えすぎる 弱さも 言えると 評価が 上がります - 「位置 m から n までだけを
逆に できますか?」と、 一部だけ逆に する 続きが 来る こともあります
ジュニアの
アルゴリズムのチートシートの「配列と文字列」に、この型の要点を表とコードでまとめています。
まず 考える手順
段 1
まずは
段 2
付け替えでnext をnext をnxt に
段 3
指を 3 つprev (最初はcur、nxt です。prev をcur をcur がprev が
段 4
再帰でもnext をnext を
解答
Python
Python
def reverse_list(head):
prev = None
cur = head
while cur:
nxt = cur.next
cur.next = prev
prev = cur
cur = nxt
return prevJavaScript
JavaScript
function reverseList(head) {
let prev = null;
let cur = head;
while (cur !== null) {
const nxt = cur.next;
cur.next = prev;
prev = cur;
cur = nxt;
}
return prev;
}Go
Go
func reverseList(
head *ListNode,
) *ListNode {
var prev *ListNode
cur := head
for cur != nil {
nxt := cur.Next
cur.Next = prev
prev = cur
cur = nxt
}
return prev
}空のprev のnext が
計算量
- 時間は O(n) です。
どの 節も 1 回ずつ 見て、 つなぎ先を 1 回だけ 書き換えます - 使う
記憶は O(1) です。 指 3 つだけで、 節は 作りません - 段 4 の
再帰で 書くと、 時間は 同じ O(n) ですが、 呼び出しの 段が 節の 数だけ積まれるので 記憶は O(n) です
よく ある間違い
- 次の
節を 取っておく 前に nextを書き換える。 cur.next = prevを先に 書くと、 残りの 節へた どれなくなり、 2 つ目から 先が 消えます。 「取っておく、 向け直す、 進める」の 順を守ります curを返す。 繰り返しが終わった とき curは空です。 逆に したリストの 先頭は prevです- 元の
先頭の nextを空に し忘れる (再帰の 書き方)。 再帰で 書いて head.next.next = headだけにすると、 元の 先頭と 2 つ目が 互いを 指す輪が でき、 読む側が 止まらなくなります。 続けて head.next = Noneが要ります - 深いリストで
再帰を使う。 Python では 1000 段ほどで 止まります。 面接で 再帰を 書いたら、 この 弱さと 繰り返しの 書き方を あわせて話します
解答を動かした版 Python 3.12.14Node.js 22.23.4Go 1.24.6確認日 2026年10月30日
面接での 話し方の例
書き始める
「値を
写して 作り直すと 記憶が O(n) 要るので、 今ある 節の nextを前向きに 付け替えます。 書き換えると 先へた どれなくなるので、 先に 次の 節を 取って おきます。 前、 いま、 次の 3 つの 指で 1 回なめるので、 時間は O(n)、 記憶は O(1) です。 再帰でも 書けますが、 節の 数だけ段が 深くなるので、 ここでは 繰り返しにします。」
書き終えたら、
「例 1 の
[3, 8, 1, 5]でたどります。 最初は 3 の nextを空へ 向け、 prevが 3 になります。 次に 8 を 3 へ 向け、 1 を 8 へ、 5 を 1 へ 向けます。 curが空に なった とき prevは 5 なので、5、 1、 8、 3 の 順の リストが 返ります。」
