力扣題解2-兩數相加

小怪物要打怪發表於2024-07-29

問題的描述如下:

分析過程:

為了解決這個問題,我們需要逐位相加兩個連結串列對應位置的值,並處理進位問題。具體步驟如下:

  1. 初始化一個新的連結串列,用於儲存結果。
  2. 使用兩個指標遍歷兩個輸入連結串列,逐位相加,同時考慮進位。
  3. 如果一個連結串列比另一個短,則將其視為 0 進行計算。
  4. 處理最後可能存在的進位。

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

詳細步驟:

  1. 初始化

    • 建立一個哨兵節點 dummy_head,用於方便返回結果連結串列。
    • 設定一個指標 current 指向哨兵節點。
    • 初始化進位 carry 為 0。
  2. 遍歷兩個連結串列

    • l1l2 未遍歷完時,進行迴圈。
    • 獲取當前節點的值 xy,如果連結串列已經遍歷完則取 0。
    • 計算當前位的和 sum = carry + x + y
    • 更新進位 carry = sum // 10
    • 建立新節點儲存當前位的值 sum % 10,並將其連結到結果連結串列中。
    • 移動 current 指標到新建立的節點。
    • 如果 l1 未遍歷完,則移動到下一個節點,同樣處理 l2
  3. 處理最後的進位

    • 如果最後計算完還有進位,則建立一個新節點儲存進位值。
  4. 返回結果連結串列

    • 返回哨兵節點 dummy_head 的下一個節點,即結果連結串列的頭節點。

這樣,我們就可以透過這個函式將兩個連結串列表示的數字相加,並以連結串列形式返回結果。

連結串列(Linked List)

連結串列是一種線性資料結構,其中的元素是節點(Node),每個節點包含資料和指向下一個節點的引用(或指標)。連結串列的長度可以動態變化,因此在需要頻繁插入和刪除操作的場景中非常有用。連結串列主要分為以下幾種型別:

  1. 單向連結串列(Singly Linked List)
  2. 雙向連結串列(Doubly Linked List)
  3. 迴圈連結串列(Circular Linked List)

單向連結串列

在單向連結串列中,每個節點只包含一個指向下一個節點的引用。連結串列的第一個節點稱為頭節點(Head),最後一個節點的 next 引用指向 None,表示連結串列的結束。

定義單向連結串列節點類

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val  # 節點儲存的資料
        self.next = next  # 指向下一個節點的引用

基本操作

  1. 初始化連結串列
  2. 插入節點
  3. 刪除節點
  4. 遍歷連結串列
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

基本操作

  1. 初始化連結串列
  2. 插入節點
  3. 刪除節點
  4. 遍歷連結串列
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)

相關文章