返回

深度解析 LeetCode 002:两数相加的巧妙技巧与 Python 实现

人工智能

导言

踏入算法和数据结构的殿堂,LeetCode 002:两数相加便是不可忽视的一道经典题目。这道题目要求我们将两个以逆序链表表示的整数相加,返回它们的和同样以逆序链表表示。

理解题意

给定两个非空链表 l1l2,其中每个链表的节点包含一个数字,并且这些数字按逆序排列,表示一个整数。我们的目标是将这两个整数相加,并将结果以一个新的逆序链表返回。

巧妙的思路

解决这道题目的关键在于巧妙地利用逆序链表的特性。我们可以从两个链表的尾节点开始遍历,逐位相加并处理进位。具体步骤如下:

  1. 设置两个指针 pq 分别指向 l1l2 的尾节点。
  2. 初始化一个新的链表 res 来存储结果。
  3. 循环遍历两个链表,只要 pq 不为 None
    • 计算当前位上的和 sum,并将其取模 10 得到当前位上的数字。
    • 将当前位上的数字添加到 res 链表的头部。
    • sum 除以 10 得到进位 carry
    • pq 分别向后移动一位。
  4. 如果存在进位 carry,将其添加到 res 链表的头部。
  5. 返回 res 链表。

Python 实现

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def addTwoNumbers(l1: ListNode, l2: ListNode) -> ListNode:
    p, q = l1, l2
    dummy = ListNode()
    cur = dummy

    carry = 0  # 进位

    while p or q or carry:
        x = p.val if p else 0
        y = q.val if q else 0

        sum = x + y + carry
        carry = sum // 10
        cur.next = ListNode(sum % 10)

        cur = cur.next
        p = p.next if p else None
        q = q.next if q else None

    return dummy.next

优化技巧

  • 利用哨兵节点: 在链表头部添加一个哨兵节点可以简化代码,避免特殊情况的处理。
  • 合并循环: 将计算和、处理进位、移动指针三个步骤合并到一个循环中,可以提高代码效率。
  • 提前终止循环: 当两个链表都遍历完且没有进位时,可以提前终止循环。

总结

LeetCode 002:两数相加是一道经典的算法和数据结构题目,涉及链表操作、进位处理和递归思想。通过巧妙的思路和优化技巧,我们可以轻松解决这道题目,巩固我们的算法基础。祝大家算法之路一帆风顺!