0002.两数相加

难度:🟡 中等

标签链表数学递归

链接2. 两数相加

题目描述

给你两个 非空 的链表,表示两个非负整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例 1:

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

示例 2:

输入:l1 = [0], l2 = [0]
输出:[0]

示例 3:

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

解题思路

核心思想

本题的核心是模拟我们小学时学过的竖式加法。由于链表的数字是逆序存储的,链表头节点对应的是数字的个位,这恰好与我们做加法时从最低位(个位)开始计算的顺序一致。我们需要从两个链表的头部开始,逐位相加,并处理好每一位的进位。

思路选择

迭代法 + 虚拟头节点(Dummy Head) 是解决此问题的标准最优思路。

  • 虚拟头节点:创建一个临时的 dummy 节点作为新链表的伪头节点。这样做的好处是,我们可以用一个统一的逻辑来处理所有节点的插入,而无需为新链表的第一个节点编写特殊的处理代码。

  • 迭代:使用一个 while 循环,只要两个链表中还有一个有节点,或者最后还有一个进位,就持续进行加法操作。

关键步骤

  1. 初始化:创建一个虚拟头节点 dummy = new ListNode(0),一个 current 指针指向它,以及一个进位变量 carry = 0

  2. 循环计算:当 l1l2 不为空,或者 carry 不为 0 时,持续循环。 a. 取值:获取 l1l2 当前节点的值,如果某个链表已经遍历完,则其值视为 0。 b. 求和:计算当前位的和 sum = val1 + val2 + carry。 c. 创建新节点:用 sum % 10 的值创建一个新节点,并将其链接到 current.next。 d. 更新进位:更新 carry = Math.floor(sum / 10)。 e. 移动指针:将 current 指针和 l1l2(如果非空)的指针都向后移动一位。

  3. 返回结果:循环结束后,dummy.next 指向的就是结果链表的真正头节点。

代码实现

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 * this.val = (val===undefined ? 0 : val)
 * this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function(l1, l2) {
    const dummyHead = new ListNode(0);
    let current = dummyHead;
    let carry = 0;

    while (l1 !== null || l2 !== null || carry !== 0) {
        const val1 = l1 ? l1.val : 0;
        const val2 = l2 ? l2.val : 0;
        const sum = val1 + val2 + carry;

        carry = Math.floor(sum / 10);
        current.next = new ListNode(sum % 10);

        current = current.next;
        if (l1) l1 = l1.next;
        if (l2) l2 = l2.next;
    }

    return dummyHead.next;
};

复杂度分析

  • 时间复杂度O(max(m, n)) 其中 m 和 n 分别是两个链表的长度。我们需要遍历完两个链表中较长的那一个。

  • 空间复杂度O(max(m, n)) 结果链表的长度最多为 max(m, n) + 1,因此空间消耗与最长链表的长度成正比。

相关题目

总结

本题是链表操作的经典入门题。它考察了对链表的基本遍历、节点创建以及处理进位等细节的能力。虚拟头节点(Dummy Head)的技巧在本题中尤为实用,大大简化了代码逻辑。

Copyright © Jun 2025 all right reserved,powered by Gitbook该文件修订时间: 2025-07-03 17:35:08

results matching ""

    No results matching ""

    results matching ""

      No results matching ""