題目:兩數相加
該題目沒有技巧和算法的考察,只是在挑戰一些很容易出錯的細節問題
right-code
# 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
"""
head = ListNode(0)
tmp = head
add_one = 0
while l1 is not None or l2 is not None:
a = l1.val if l1 else 0
b = l2.val if l2 else 0
s = a + b + add_one # 使用s變量承接加和結果,作爲下一個節點.val變量的結果憑據
if l1 is not None:
l1 = l1.next
if l2 is not None:
l2 = l2.next
add_one = 1 if s >= 10 else 0 # 進位計算
s = s % 10
tmp.next = ListNode(s)
tmp = tmp.next
if add_one == 1:
tmp.next = ListNode(1)
return head.next
【思路】:
- l1/l2兩個鏈表都空的情況下,結束循環。所以確定外層while循環的條件;
- l1/l2哪個鏈表爲空,就應該把它當成0計算;不爲空,就讓他next。
- 有進位的情況需要被記錄,所以新開一個變量add_one,專門用於記錄進位與否;
- 當前節點生成next新節點並移動tmp指針指向;
- 整體循環結束後,若add_one節點是1,則需要在最後補上一個節點。0不需要補。
其實整體流程下來是真簡單,但有很多坑到死的小細節,這些地方纔是本題精髓:
tmp
指針應指向當前節點。若指向下一個節點,則會導致,當最後一位的加和無需進位時,你沒法刪除最後一個ListNode(0)
。所以我們一上來就隨意初始化一個head頭結點,然後最終返回的是head.next
,因爲你只有在A節點的前驅節點上的時候,纔可以執行A節點的刪除/添加操作(通過操作A的前驅節點的.next
指針達成);- 新節點的取值應該新開一個變量存儲(line 20)
對比我之前死活提示我“超出時間限制”的代碼(下方錯誤代碼“wrong-code”)。我之前的錯誤代碼,就是因爲直接修改了tmp.val
參數。要注意,因爲實際上tmp
指針是指向當前節點的,而實際上我們計算得到的tmp.val
是下一個節點tmp.next
的取值。所以二者不能等同,直接用tmp.val
接收計算結果(而不是s
),會導致當前節點的.val
參數被修改,這是不對滴
錯誤代碼 wrong-code,未採用新變量存儲加和結果
# 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
"""
head = ListNode(0)
tmp = head
add_one = 0
while l1 is not None or l2 is not None:
a = l1.val if l1 else 0
b = l2.val if l2 else 0
tmp.val = a + b + add_one # 錯誤在這裏,未使用額外變量s接收加和結果,導致當前節點的.val變量被改動;實際上當前節點的.val參數應該是在tmp指針指向其前驅節點時就已被定義好的。
if l1.next is not None:
l1 = l1.next
if l2.next is not None:
l2 = l2.next
add_one = tmp.val // 10 # 進位計算
tmp.val =int(str(tmp.val)[-1])
tmp.next = ListNode(tmp.val)
tmp = tmp.next
if add_one == 1:
tmp.next = ListNode(1)
return head.next