【LeetCode 2】力扣算法:两数相加

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

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

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

提示:

  • 每个链表中的节点数在范围 [1, 100] 内
  • 0 <= Node.val <= 9
  • 题目数据保证列表表示的数字不含前导零

image


要将两个逆序存储的链表表示的非负整数相加,我们可以模拟手算加法的过程。

算法步骤:

  1. 初始化:创建一个虚拟头节点 dummyHead,用于简化结果链表的构建。同时,初始化一个指针 res 指向 dummyHead,用于构建结果链表。还需要一个变量 carry 来存储进位。

  2. 逐位相加:遍历两个链表,对每一位进行相加,同时加上上一次迭代的进位 carry。更新 carry 为新的进位。

  3. 处理进位:如果遍历完两个链表后仍有进位,需要继续创建新的节点直到进位为0。

  4. 返回结果:返回 dummyHead.next,即结果链表的头节点。

复杂度分析:

  • 时间复杂度:O (max(m, n)),其中 m 和 n 分别是两个链表的长度。我们最多遍历两个链表的长度。

  • 空间复杂度:O (max(m, n)),因为需要创建新的节点来存储结果。在最坏的情况下,如果两个链表长度相等,且每一位相加都产生进位,需要创建与链表长度相同的新节点。

我的 Java 代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        
        ListNode dummyHead = new ListNode(0);  // 创建一个虚拟头节点
        ListNode res = dummyHead;
        int carry = 0;  // 存储进位值

        // 逐位相加
        while(l1 != null || l2 != null){
            int val1 = (l1==null)? 0:l1.val;
            int val2 = (l2==null)? 0:l2.val;
            int sum = val1+val2+carry;  // 当前位的和加上进位
            carry = sum/10;   // 更新进位值
            res.next = new ListNode(sum % 10); // 创建新节点,存储当前位的结果
            // 移动链表指针
            res = res.next;
            if(l1 != null)   l1 = l1.next;
            if(l2 != null)   l2 = l2.next;
        }

        // 如果最后还有进位,要添加一个新的节点
        if(carry>0){
            res.next = new ListNode(carry);
        }

        return dummyHead.next;

    }
}
posted @ 2025-07-29 14:30  junjunyi  阅读(65)  评论(0)    收藏  举报