Pythonで連結リストとして表された2つの数値の和を求めるプログラム
この記事では、単方向連結リスト(Singly Linked List)で表された2つの数値を加算し、その結果を新しい連結リストとして返す方法を解説します。
ここでのポイントは、各リストが「最下位桁から順に」数値を格納しているという点です。例えば、リスト [5, 6, 4] は数値「465」を表し、リスト [2, 4, 8] は数値「842」を表します。これらを足すと 465 + 842 = 1307 となるため、出力は [7, 0, 3, 1] になります。
アルゴリズムの考え方
筆算と同じ要領で、各桁を順番に足し合わせながら繰り上がり(carry)を管理します。具体的な手順は以下の通りです。
- 繰り上がりを保持する変数 carry を 0 で初期化します。
- 結果リストの先頭となるダミーノード res(値は 0)を作成し、作業用ポインタ curr を res に設定します。
- L1 または L2 のどちらかに要素が残っている間、あるいは carry が 0 でない限り、以下を繰り返します。
- L1 の現在の値を l0_val とする(L1 が空なら 0)
- L2 の現在の値を l1_val とする(L2 が空なら 0)
- sum_ = l0_val + l1_val を計算
- (sum_ + carry) を 10 で割った商を新しい carry に、余りを add_val に設定
- add_val を値とする新ノードを curr.next に接続し、curr を一つ進める
- L1 と L2 をそれぞれ次のノードへ進める(空なら None)
- ループ終了後、curr.next を None にしてリストを閉じます。
- res.next(ダミーノードの次)を結果として返します。
実装例
それでは、実際のPythonコードを見てみましょう。
class ListNode:
def __init__(self, data, next=None):
self.val = data
self.next = next
def make_list(elements):
head = ListNode(elements[0])
for element in elements[1:]:
ptr = head
while ptr.next:
ptr = ptr.next
ptr.next = ListNode(element)
return head
def print_list(head):
ptr = head
print('[', end='')
while ptr:
print(ptr.val, end=', ')
ptr = ptr.next
print(']')
class Solution:
def solve(self, L1, L2):
carry = 0
res = ListNode(0)
curr = res
while L1 or L2 or carry:
l0_val = L1.val if L1 else 0
l1_val = L2.val if L2 else 0
sum_ = l0_val + l1_val
carry, add_val = divmod(sum_ + carry, 10)
curr.next = ListNode(add_val)
curr = curr.next
L1 = L1.next if L1 else None
L2 = L2.next if L2 else None
curr.next = None
return res.next
ob = Solution()
L1 = make_list([5, 6, 4])
L2 = make_list([2, 4, 8])
print_list(ob.solve(L1, L2))入力
[5,6,4], [2,4,8]
出力
[7, 0, 3, 1]
コードのポイント
- divmod関数の活用: Pythonの divmod(a, b) は商と余りを同時に返すため、繰り上がりの計算が1行で簡潔に書けます。
- ダミーノード: 値 0 のダミーノード res を使うことで、結果リストの先頭処理を特別扱いせずに済み、最後に res.next を返すだけで済みます。
- 桁数が異なる場合にも対応: ループ条件に「L1 or L2 or carry」を採用しているため、片方のリストが短い場合や、最終的な繰り上がりが発生する場合でも正しく動作します。
このアルゴリズムの計算量は、リストの長さを n とした場合に O(n)、必要な追加メモリも結果リスト分のみなので O(n) となります。LeetCodeの「Add Two Numbers」(問題2)などでもおなじみの定番テクニックですので、ぜひマスターしておきましょう。
-
Pythonで連結リストを使って2つの多項式を加算するプログラムの作り方
問題の概要 この記事では、連結リストで表現された2つの多項式を加算するPythonプログラムを紹介します。 2つの多項式が与えられ、それらの和を求めることを考えます。多項式は連結リストとして表現し、多項式の各項は連結リストの1つのノードに対応させます。各ノードには「係数」「次数(べき指数)」、そして「次のノードへの参照(ポインタ)」を持たせます。最終的なゴールは、2つの多項式の和を表す新しい連結リストを返すことです。 たとえば、入力が以下の画像のような2つの多項式だった場合を見てみましょう。 1x^1 + 1x^2 = 0 と 2x^1 + 3x^0 = 0 この場合、出力は次のようになりま
-
3つの数値から最大値を見つけるPythonプログラム
このチュートリアルでは、3つの数値の中から最大値を求めるPythonプログラムを作成します。3つの数値が与えられたとき、その中で最も大きい数値を見つけることが目標です。まず、理解を深めるためにサンプルのテストケースをいくつか見てみましょう。入力: a, b, c = 2, 34, 4 出力: 34入力: a, b, c = 25, 3, 12 出力: 25入力: a, b, c = 5, 5, 5 出力: 5それでは、3つの数値の中から最大値を求める手順を見ていきましょう。アルゴリズム1. 3つの数値 a、b、c を初期化する。 2. a が b と c の両方より大きければ、a を出力する。