兩數相加:鏈表表示的逆序整數求和
在這篇技術博客中,我們將討論一個力扣(LeetCode)上的編程題目:兩數相加。這個問題要求我們處理兩個非空鏈表,它們表示兩個非負整數。每個鏈表中的數字都是逆序存儲的,我們需要將這兩個整數相加,并以相同的形式返回一個表示和的鏈表。
題目描述
給你兩個非空的鏈表,表示兩個非負的整數。它們每位數字都是按照逆序的方式存儲的,并且每個節點只能存儲一位數字。
請你將兩個數相加,并以相同形式返回一個表示和的鏈表。
你可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。
示例
示例 1:
輸入:l1 = , l2 =
輸出:
解釋:342 + 465 = 807.
示例 2:
輸入:l1 = , l2 =
輸出:
示例 3:
輸入:l1 = , l2 =
輸出:[8,9,9,9,
- 每個鏈表中的節點數在范圍 [1, 100] 內
- 0 <= Node.val <= 9
- 題目數據保證列表表示的數字不含前導零
解題思路
為了解決這個問題,我們可以模擬整數加法的過程。首先,我們需要從兩個鏈表的頭節點開始,將它們的值相加,然后考慮進位。接下來,我們將兩個鏈表的指針向后移動,并重復這個過程,直到到達鏈表的尾部。如果在鏈表的尾部仍然有進位,我們需要添加一個新的節點來存儲這個進位。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:res = ListNode() t = rest.val = (l1.val + l2.val) % 10temp = (l1.val + l2.val) // 10while l1.next or l2.next:t.next = ListNode()t = t.nextif l1.next and l2.next:l1 = l1.nextl2 = l2.nextt.val = (l1.val + l2.val + temp) % 10temp = (l1.val + l2.val + temp) // 10elif l1.next and not l2.next:l1 = l1.nextt.val = (l1.val + temp) % 10temp = (l1.val + temp) // 10elif l2.next and not l1.next:l2 = l2.nextt.val = (l2.val + temp) % 10temp = (temp + l2.val) // 10if temp:t.next = ListNode(temp)return res
代碼提煉簡化
關鍵的優化點,以及如何從原始代碼逐步轉換為優化后的代碼:
-
統一處理循環條件:原始代碼中,我們需要在循環內部分別處理
l1
和l2
的情況。優化后的代碼將這些條件合并到一個循環中,使得代碼更簡潔。我們使用l1 or l2 or carry
作為循環條件,這樣可以確保在兩個鏈表都遍歷完且無進位時才退出循環。 -
簡化值獲取:在原始代碼中,我們需要在循環內部分別獲取
l1
和l2
的值。優化后的代碼通過使用val1 = l1.val if l1 else 0
和val2 = l2.val if l2 else 0
來簡化值的獲取。這樣,我們可以在一行代碼中處理l1
和l2
是否存在的情況,避免了額外的條件判斷。 -
簡化進位處理:原始代碼中,我們需要在循環內部分別計算和更新進位值。優化后的代碼將進位處理邏輯簡化為
carry = total // 10
。這樣,我們可以在一行代碼中更新進位值,避免了額外的條件判斷。 -
簡化鏈表節點創建:原始代碼中,我們需要在循環內部分別創建新的鏈表節點。優化后的代碼通過使用
t.next = ListNode(total % 10)
來簡化鏈表節點的創建。這樣,我們可以在一行代碼中創建新的鏈表節點,避免了額外的條件判斷。 -
簡化鏈表遍歷:在原始代碼中,我們需要在循環內部分別更新
l1
和l2
。優化后的代碼通過使用l1 = l1.next if l1 else None
和l2 = l2.next if l2 else None
來簡化鏈表的遍歷。這樣,我們可以在一行代碼中處理l1
和l2
是否存在的情況,避免了額外的條件判斷。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:res = ListNode()t = rescarry = 0while l1 or l2 or carry:if l1:val1 = l1.vall1 = l1.nextelse:val1 = 0if l2:val2 = l2.vall2 = l2.nextelse:val2 = 0total = val1 + val2 + carrycarry = total // 10t.next = ListNode(total % 10)t = t.nextreturn res.next
總結
這個問題是一個很好的鏈表操作練習,可以幫助我們熟悉鏈表的基本操作和加法運算的處理。