問題的描述如下:
分析過程:
為了解決這個問題,我們需要逐位相加兩個連結串列對應位置的值,並處理進位問題。具體步驟如下:
- 初始化一個新的連結串列,用於儲存結果。
- 使用兩個指標遍歷兩個輸入連結串列,逐位相加,同時考慮進位。
- 如果一個連結串列比另一個短,則將其視為 0 進行計算。
- 處理最後可能存在的進位。
Python 實現:
首先,我們需要定義連結串列節點的類 ListNode
,然後編寫求和的函式 addTwoNumbers
。
定義連結串列節點類:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
實現求和函式:
def addTwoNumbers(l1, l2):
dummy_head = ListNode(0) # 哨兵節點,便於返回結果連結串列
current = dummy_head
carry = 0 # 初始化進位為0
while l1 is not None or l2 is not None:
x = l1.val if l1 is not None else 0 # 獲取l1的當前值,如果l1已經遍歷完則取0
y = l2.val if l2 is not None else 0 # 獲取l2的當前值,如果l2已經遍歷完則取0
sum = carry + x + y # 計算當前位的和,包括進位
carry = sum // 10 # 更新進位
current.next = ListNode(sum % 10) # 建立新節點儲存當前位的值
current = current.next # 移動到下一個節點
if l1 is not None: l1 = l1.next # 移動l1到下一個節點
if l2 is not None: l2 = l2.next # 移動l2到下一個節點
if carry > 0:
current.next = ListNode(carry) # 如果最後有進位,建立新節點儲存進位值
return dummy_head.next # 返回結果連結串列,跳過哨兵節點
# 示例
def create_linked_list(numbers):
dummy_head = ListNode(0)
current = dummy_head
for number in numbers:
current.next = ListNode(number)
current = current.next
return dummy_head.next
def print_linked_list(node):
while node:
print(node.val, end=' -> ' if node.next else '\n')
node = node.next
l1 = create_linked_list([2, 4, 3])
l2 = create_linked_list([5, 6, 4])
result = addTwoNumbers(l1, l2)
print_linked_list(result) # 輸出:7 -> 0 -> 8
詳細步驟:
-
初始化:
- 建立一個哨兵節點
dummy_head
,用於方便返回結果連結串列。 - 設定一個指標
current
指向哨兵節點。 - 初始化進位
carry
為 0。
- 建立一個哨兵節點
-
遍歷兩個連結串列:
- 在
l1
或l2
未遍歷完時,進行迴圈。 - 獲取當前節點的值
x
和y
,如果連結串列已經遍歷完則取 0。 - 計算當前位的和
sum = carry + x + y
。 - 更新進位
carry = sum // 10
。 - 建立新節點儲存當前位的值
sum % 10
,並將其連結到結果連結串列中。 - 移動
current
指標到新建立的節點。 - 如果
l1
未遍歷完,則移動到下一個節點,同樣處理l2
。
- 在
-
處理最後的進位:
- 如果最後計算完還有進位,則建立一個新節點儲存進位值。
-
返回結果連結串列:
- 返回哨兵節點
dummy_head
的下一個節點,即結果連結串列的頭節點。
- 返回哨兵節點
這樣,我們就可以透過這個函式將兩個連結串列表示的數字相加,並以連結串列形式返回結果。
連結串列(Linked List)
連結串列是一種線性資料結構,其中的元素是節點(Node),每個節點包含資料和指向下一個節點的引用(或指標)。連結串列的長度可以動態變化,因此在需要頻繁插入和刪除操作的場景中非常有用。連結串列主要分為以下幾種型別:
- 單向連結串列(Singly Linked List)
- 雙向連結串列(Doubly Linked List)
- 迴圈連結串列(Circular Linked List)
單向連結串列
在單向連結串列中,每個節點只包含一個指向下一個節點的引用。連結串列的第一個節點稱為頭節點(Head),最後一個節點的 next
引用指向 None
,表示連結串列的結束。
定義單向連結串列節點類
class ListNode:
def __init__(self, val=0, next=None):
self.val = val # 節點儲存的資料
self.next = next # 指向下一個節點的引用
基本操作
- 初始化連結串列
- 插入節點
- 刪除節點
- 遍歷連結串列
class SinglyLinkedList:
def __init__(self):
self.head = None # 初始化連結串列,頭節點為空
def append(self, val):
new_node = ListNode(val)
if not self.head:
self.head = new_node
return
last = self.head
while last.next:
last = last.next
last.next = new_node
def delete(self, val):
current = self.head
if current and current.val == val:
self.head = current.next
current = None
return
prev = None
while current and current.val != val:
prev = current
current = current.next
if current is None:
return
prev.next = current.next
current = None
def traverse(self):
current = self.head
while current:
print(current.val, end=" -> " if current.next else "\n")
current = current.next
# 示例
linked_list = SinglyLinkedList()
linked_list.append(1)
linked_list.append(2)
linked_list.append(3)
linked_list.traverse() # 輸出:1 -> 2 -> 3
linked_list.delete(2)
linked_list.traverse() # 輸出:1 -> 3
雙向連結串列
在雙向連結串列中,每個節點包含兩個引用,一個指向下一個節點,一個指向前一個節點。
定義雙向連結串列節點類
class DoublyListNode:
def __init__(self, val=0, next=None, prev=None):
self.val = val
self.next = next
self.prev = prev
基本操作
- 初始化連結串列
- 插入節點
- 刪除節點
- 遍歷連結串列
class DoublyLinkedList:
def __init__(self):
self.head = None
def append(self, val):
new_node = DoublyListNode(val)
if not self.head:
self.head = new_node
return
last = self.head
while last.next:
last = last.next
last.next = new_node
new_node.prev = last
def delete(self, val):
current = self.head
if current and current.val == val:
self.head = current.next
if self.head:
self.head.prev = None
current = None
return
while current and current.val != val:
current = current.next
if current is None:
return
if current.next:
current.next.prev = current.prev
if current.prev:
current.prev.next = current.next
current = None
def traverse_forward(self):
current = self.head
while current:
print(current.val, end=" -> " if current.next else "\n")
current = current.next
def traverse_backward(self):
current = self.head
if not current:
return
while current.next:
current = current.next
while current:
print(current.val, end=" -> " if current.prev else "\n")
current = current.prev
# 示例
doubly_linked_list = DoublyLinkedList()
doubly_linked_list.append(1)
doubly_linked_list.append(2)
doubly_linked_list.append(3)
doubly_linked_list.traverse_forward() # 輸出:1 -> 2 -> 3
doubly_linked_list.delete(2)
doubly_linked_list.traverse_forward() # 輸出:1 -> 3
doubly_linked_list.traverse_backward() # 輸出:3 -> 1
迴圈連結串列
在迴圈連結串列中,最後一個節點的 next
引用指向頭節點,形成一個迴圈。可以是單向的也可以是雙向的。
單向迴圈連結串列節點類和基本操作
class CircularListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class CircularLinkedList:
def __init__(self):
self.head = None
def append(self, val):
new_node = CircularListNode(val)
if not self.head:
self.head = new_node
new_node.next = self.head
return
last = self.head
while last.next != self.head:
last = last.next
last.next = new_node
new_node.next = self.head
def traverse(self):
if not self.head:
return
current = self.head
while True:
print(current.val, end=" -> ")
current = current.next
if current == self.head:
break
print("(head)")
# 示例
circular_linked_list = CircularLinkedList()
circular_linked_list.append(1)
circular_linked_list.append(2)
circular_linked_list.append(3)
circular_linked_list.traverse() # 輸出:1 -> 2 -> 3 -> (head)