返回

补零巧解李氏链表相加,规避整数溢出陷阱

前端

在 LeetCode 002 两数相加问题中,需要将两个链表表示的非负整数相加。传统解法直接将各个节点的值相加,但存在整数溢出风险。本文介绍一种巧妙的补零解法,有效规避了溢出问题。

补零原理

补零解法的关键在于将两个链表长度保持一致。若两个链表长度不等,则对较短链表进行补零操作,将空位节点值设为 0。这样,两个链表的每个节点都对应一个值,可直接相加。

具体实现

算法步骤如下:

  1. 初始化两个指针 currA 和 currB,分别指向链表 A 和 B 的头部。
  2. 遍历两个链表,同时进行补零操作。
  3. 如果 currA 或 currB 指向非空节点,则将 currA.val 和 currB.val 相加并保存到变量 sum 中。
  4. 根据 sum 值计算进位值 carry,并将进位值更新到 currA 或 currB 的下一个节点中。
  5. 重复步骤 3-4,直到两个链表均遍历完毕。
  6. 若最终进位值 carry 不为 0,则创建一个新的头节点并指向 carry。

代码示例

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    ListNode dummyHead = new ListNode(0); // 虚拟头节点
    ListNode curr = dummyHead;
    int carry = 0; // 进位值

    while (l1 != null || l2 != null) {
        int sum = carry;
        if (l1 != null) {
            sum += l1.val;
            l1 = l1.next;
        }
        if (l2 != null) {
            sum += l2.val;
            l2 = l2.next;
        }
        carry = sum / 10; // 计算进位值
        curr.next = new ListNode(sum % 10); // 新节点
        curr = curr.next;
    }

    if (carry != 0) {
        curr.next = new ListNode(carry);
    }

    return dummyHead.next;
}

优势

补零解法有效避免了整数溢出问题,且代码逻辑清晰易懂。同时,该解法可扩展到更复杂的链表相加问题中,如进位值进位等。

参考

更多解法详见博文:https://ripudamanwadhwa.com/blog/add-two-numbers-linked-list