Problem
問題は LeetCode より拝借しています.
正の整数を保持する2つの単方向リストが与えられた時, 各要素を1つの桁のように考えて
2つのリストの合計値を保持するリストを返却せよ. 次の要素への桁上りも考慮すること.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Solution
整数同士の足し算の筆算を行うようなイメージです. (見た目的には低い位と高い位の順番が逆ですが)
2つのリストの先頭から開始して, 合計値を求め, 10以上の場合は次の要素の計算に1を持ち越していく繰り返しです. 先に片方のリストが空になった場合は一方の値だけを合計値として扱います. 両方のリストが空になった時点で計算は終了です.
最後の計算結果が10以上であった場合には, 最後に1を持ち越しておくことをお忘れなく.
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
dummyHead = ListNode(0);
curNode = dummyHead
if not l1 and not l2: return None
elif not l1: return l2
elif not l2: return l1
co = 0 # carry over from the previous node
while l1 or l2:
sum = 0
if l1:
sum += l1.val
l1 = l1.next
if l2:
sum += l2.val
l2 = l2.next
sum += co
co = sum / 10
sum = sum % 10
curNode.next = ListNode(sum)
curNode = curNode.next
if co == 1:
curNode.next = ListNode(1)
return dummyHead.next
Java code:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
if (l1 == null && l2 == null) return null;
else if (l1 == null) return l2;
else if (l2 == null) return l1;
ListNode dummyHead = new ListNode(0);
ListNode curNode = dummyHead;
int co = 0; // carry-over from previous nodes
while (l1 != null || l2 != null) {
int sum = 0;
if (l1 != null) {
sum += l1.val;
l1 = l1.next;
}
if (l2 != null) {
sum += l2.val;
l2 = l2.next;
}
sum += co;
co = sum / 10;
sum %= 10;
curNode.next = new ListNode(sum);
curNode = curNode.next;
}
if (co == 1) curNode.next = new ListNode(1);
return dummyHead.next;
}
}
N
を2つのリストの内長い方の長さだとして, 計算量・空間量ともにO(N)
となります.
ただし空間量に関しては, 今回のプログラムでは結果の格納に新しい単方向リストを用意していますが, 実際には片方のリストを上書きしていく形でも実行結果に影響は及ぼしません. この場合は余分な空間量は消費しないことになります.