力扣题解2-两数相加

问题的描述如下:

分析过程:

为了解决这个问题,我们需要逐位相加两个链表对应位置的值,并处理进位问题。具体步骤如下:

  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)
posted @ 2024-07-29 17:36  小怪物要打怪  阅读(52)  评论(0)    收藏  举报