☰
LeetCode两数相加:链表操作与竖式加法模拟
2026/11/5 2:24:16 网站建设 项目流程

1. 题目解析与需求拆解

这道题目来自LeetCode热题100的第2题"两数相加",属于链表操作类的基础算法题。题目要求我们处理两个非空链表,它们各自代表一个逆序存储的非负整数,需要将这两个数相加并以相同形式返回结果链表。

举个例子,如果输入是链表A:2->4->3和链表B:5->6->4,那么它们实际代表的数字分别是342和465。相加结果是807,我们需要返回链表C:7->0->8。这种逆序存储的设计其实降低了题目难度,因为数字的个位正好对应链表头,符合我们日常加法从低位开始的运算习惯。

2. 核心算法思路

2.1 模拟竖式加法

这道题最直接的解法就是模拟我们小学学过的竖式加法。我们需要同时遍历两个链表,逐位相加并处理进位。具体来说有以下几个关键点:

  1. 初始化一个哑节点(dummy node)作为结果链表的起始点,这样可以避免处理头节点的特殊情况
  2. 使用一个变量carry来记录进位值,初始为0
  3. 同时遍历两个链表,直到两个链表都到达末尾且没有剩余进位
  4. 每次迭代时:
    • 计算当前位的和:链表A当前节点的值 + 链表B当前节点的值 + carry
    • 确定当前位的值:sum % 10
    • 更新进位:carry = sum // 10
    • 创建新节点并连接到结果链表
    • 移动所有链表指针到下一个节点

2.2 边界情况处理

在实际编码中,有几个边界情况需要特别注意:

  1. 两个链表长度不等时,短链表遍历完后要继续处理长链表剩余部分
  2. 最后如果还有进位(carry > 0),需要额外创建一个节点
  3. 输入链表可能为空(虽然题目说明是非空链表,但好的习惯是防御性编程)

3. 代码实现与详细注释

# 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]: dummy = ListNode() # 创建哑节点作为结果链表的起始点 current = dummy # 当前节点指针 carry = 0 # 进位初始化为0 # 遍历直到两个链表都到达末尾且没有剩余进位 while l1 or l2 or carry: # 获取当前节点的值,如果节点为空则视为0 val1 = l1.val if l1 else 0 val2 = l2.val if l2 else 0 # 计算当前位的和 total = val1 + val2 + carry carry = total // 10 # 计算新的进位 digit = total % 10 # 计算当前位的值 # 创建新节点并连接到结果链表 current.next = ListNode(digit) current = current.next # 移动链表指针 if l1: l1 = l1.next if l2: l2 = l2.next return dummy.next # 返回哑节点的下一个节点,即真正的结果链表头

4. 复杂度分析与优化空间

4.1 时间复杂度

算法的时间复杂度是O(max(m,n)),其中m和n分别是两个输入链表的长度。因为我们需要遍历两个链表中较长的那个,且每个节点只被访问一次。

4.2 空间复杂度

空间复杂度也是O(max(m,n)),因为我们需要创建一个新的链表来存储结果,最坏情况下结果链表的长度会比输入链表中最长的那个多1(因为有进位)。

4.3 可能的优化方向

虽然这个解法已经相当高效,但仍有几个可能的优化点:

  1. 可以尝试复用较长的输入链表来存储结果,减少内存分配
  2. 对于特别长的链表,可以考虑并行计算(虽然对于算法题来说不太必要)
  3. 如果输入链表是正序存储的(即头节点是最高位),可以考虑使用栈来反转链表

5. 常见错误与调试技巧

5.1 常见错误类型

在解决这个问题时,新手常犯的错误包括:

  1. 忘记处理最后的进位,导致结果少一位
  2. 在链表长度不等时,没有正确处理其中一个链表已经遍历完的情况
  3. 没有使用哑节点,导致头节点处理逻辑复杂
  4. 在移动链表指针时没有检查是否为空,导致空指针异常

5.2 调试技巧

当你的代码出现问题时,可以尝试以下调试方法:

  1. 使用简单的测试用例,如两个一位数的链表相加
  2. 打印中间变量,特别是carry的值和当前节点的值
  3. 手动模拟算法执行过程,在纸上画出链表的变化
  4. 检查循环终止条件是否正确,确保所有情况都被覆盖

6. 扩展思考与实际应用

6.1 变种问题

这道题目有几个有趣的变种值得思考:

  1. 如果链表存储的数字是正序的(即头节点是最高位),如何解决?
  2. 如果允许链表中有负数,该如何处理?
  3. 如果不是十进制,而是其他进制(如二进制)的加法,算法需要如何调整?

6.2 实际应用场景

链表加法在实际中有多种应用:

  1. 大整数运算:当数字太大无法用基本数据类型表示时,可以用链表存储
  2. 多项式相加:多项式的系数可以用链表存储,加法算法类似
  3. 某些加密算法中需要处理大数的运算

提示:在面试中,面试官可能会要求你解释算法的每一步,所以务必理解透彻每个细节。同时,准备好讨论时间/空间复杂度以及可能的优化方向。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询