問題
小さいhead1 と head2 を
- 各節は
val(値) とnext(次の節) を 持ちます。 最後の 節の nextは、Python では None、JavaScript では null、Go では nilです。Go の 節は ListNodeで、Val、Nextと大文字で 始まります - どちらの
リストも 小さい 順に 並んでいます。 同じ 値が 続く こともあります - 今ある
節の つなぎ先を 付け替えて まとめてください。 比べる ための 目印の 節 (ダミー) は 1 つ 作ってかまいません - どちらか、
または 両方の リストが 空の こともあります。 両方が 空なら 空のまま返します - それぞれの
節の 数は 0 以上 50 以下、 値は どれも -100 以上 100 以下です
例では、
入力と出力の例
例 1
同じ値の 5 は、
入力
head1 = [2, 5, 9]
head2 = [1, 5, 6, 12]出力
[1, 2, 5, 5, 6, 9, 12]例 2
片方が
入力
head1 = []
head2 = [4, 7]出力
[4, 7]例 3
両方
入力
head1 = []
head2 = []出力
[]面接での聞かれ方
連結リストの
- 「並んだ 2 本の
連結リストを、 並んだ 1 本に まとめてください」 - 書き終えた
あとに 「k 本の リストなら どうしますか?」と 続きを 聞かれる ことがあります。 2 本ずつまとめる 書き方と、 優先度付きの 待ち行列 (ヒープ) で k 本の 先頭を 比べる 書き方が あり、 後者は シニアの問題です - 「ダミーの
節を 使わずに 書けますか?」 「再帰でも書けますか?」と、 書き方を 変えて 聞かれる こともあります
ジュニアの
アルゴリズムのチートシートの「配列と文字列」に、この型の要点を表とコードでまとめています。
まず 考える手順
段 1
まずは
段 2
2 本とも
段 3
最初の 1 つをdummy をdummy.next を
段 4
どちらかが
解答
Python
Python
def merge_sorted_lists(
head1, head2
):
dummy = ListNode(0)
tail = dummy
a, b = head1, head2
while a and b:
if a.val <= b.val:
tail.next = a
a = a.next
else:
tail.next = b
b = b.next
tail = tail.next
tail.next = a if a else b
return dummy.nextJavaScript
JavaScript
function mergeSortedLists(
head1, head2
) {
const dummy = new ListNode(0);
let tail = dummy;
let a = head1;
let b = head2;
while (a !== null
&& b !== null) {
if (a.val <= b.val) {
tail.next = a;
a = a.next;
} else {
tail.next = b;
b = b.next;
}
tail = tail.next;
}
tail.next = a ?? b;
return dummy.next;
}Go
Go
func mergeSortedLists(
head1, head2 *ListNode,
) *ListNode {
dummy := &ListNode{}
tail := dummy
a, b := head1, head2
for a != nil && b != nil {
if a.Val <= b.Val {
tail.Next = a
a = a.Next
} else {
tail.Next = b
b = b.Next
}
tail = tail.Next
}
if a != nil {
tail.Next = a
} else {
tail.Next = b
}
return dummy.Next
}tail は、<= で head1 側を
計算量
- 時間は O(n + m) です。
n と m は 2 本の 節の 数で、 どの 節も 1 回だけつなぎます。 残りを 丸ごとつな ぐ所は 1 回で済みます - 使う
記憶は O(1) です。 ダミーの 節 1 つと 指だけで、 ほかの 節は 今ある 物を つなぎ直しています
よく ある間違い
- 片方が
尽きた あと、 残りを つなぎ忘れる。 繰り返しを 抜けた ところで 終えると、 例 1 の 9 と 12 のような 残りが 消えます。 最後に 残った 側を 丸ごとつなぎます dummyを返す。dummyは目印で 値を 持たないので、 返すのは dummy.nextです。dummyを返すと、 先頭に 0 が 1 つ増えます tailを進め忘れる。 つないだあとに tail = tail.nextが無いと、 毎回 dummyの後ろを 上書きし、 最後に つないだ節から 先しか 残りません - ダミーを
使わずに、 先頭の 場合分けで迷う。 空の リストや 片方だけ 空の 場合を 別々に 書き始めると、 抜けが 出やすくなります。 ダミーを 置けば、 1 つの 繰り返しで 全部の 場合が通ります
解答を動かした版 Python 3.12.14Node.js 22.23.4Go 1.24.6確認日 2026年10月30日
面接での 話し方の例
書き始める
「全部集めて
並べ替えると O(n log n) です。 2 本とも 並んでいるので、 次に 来るのは 必ずどちらかの 先頭です。 先頭どうしを 比べて 小さい 方を つなぐのを 繰り返し、 片方が 尽きたら 残りを 丸ごとつなぎます。 先頭の 場合分けを 無く すために ダミーの 節を 置きます。 時間は O(n + m)、 記憶は O(1) です。」
書き終えたら、
「例 1 で
たどります。 2 と 1 では 1 を つなぎ、 2 と 5 では 2 を、 5 と 5 では 左の 5 を つなぎます。 次の 9 と 5 で 右の 5、 9 と 6 で 6、 9 と 12 で 9 を つなぐと、 左が 尽きます。 残りの 12 を 丸ごとつないで、 1、 2、 5、 5、 6、 9、 12 に なります。」
