問題描述
給出兩個非空的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照逆序的方式存儲的,並且它們的每個節點只能存儲 一位數字。如果,我們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。
示例:
輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
原因:342 + 465 = 807
測試用例 | 說明 |
---|---|
當一個列表比另一個列表長時。 | |
當一個列表爲空時,即出現空列表。 | |
求和運算最後可能出現額外的進位,這一點很容易被遺忘 |
Sol 1:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
re = ListNode(0)
r=re
carry=0
while(l1 or l2):
x= l1.val if l1 else 0 #往後面補0
y= l2.val if l2 else 0
s=carry+x+y #進位,超過十進一
carry=s//10 #取整的正確用法
r.next=ListNode(s%10) #取餘
r=r.next
if(l1!=None):l1=l1.next
if(l2!=None):l2=l2.next
if(carry>0): #如果最後一位相加超過10,再進一位給一 4000+6000=10000
r.next=ListNode(1)
return re.next
這裏要提醒各位:如果自己寫的過程中超時了,說明你的代碼有問題,可能運行時間超過的規定。(也許你在本地環境下是可以運行的,但在這裏不夠好)
代碼解析:
- 注意這裏的鏈表概念,代碼中首先初始化了一個鏈表re,然後又複製了這個鏈表r(這兩個鏈表的指向相同),由於在鏈表移動的過程中要不停的變換當前的地址,指向下一個地址,所以r鏈表充當這個角色,不停的指向下一個地址。但是,re指向的是r經過的所有地址,如圖所示,r最後的val爲8,而re.next指向的是7,0,8。
- 其次,這裏還用的,用進位來代替位數相加由於每位數字都應當處於 的範圍內,我們計算兩個數字的和時可能會出現“溢出”。例如,。在這種情況下,我們會將當前位的數值設置爲 ,並將進位 帶入下一次迭代。進位 carry必定是 或,這是因爲兩個數字相加(考慮到進位)可能出現的最大和爲 。
時間複雜度:,假設 和 分別表示 和 的長度,上面的算法最多重複 次。
空間複雜度:,新列表的長度最多爲 。運行時間爲116ms,內存佔用爲6.7M。