思路分析:两个链表中节点数据倒序存储,但是两个链表左端对齐后,同一位置的数字可以直接相加,进位 1 向后一位传递。所以同时遍历两个链表,逐位计算它们的和,并与当前位置的进位值相加。进位值只有 0 和 1 两种情况,初始时可以设置为 0。

举个例子来说,遍历某一链表位置时,当前位置的数字为 n1,n2,进位值为 carry,则它们的和为 n1 + n2 + carry;那么结果链表对应位置数字为 (n1 + n2 + carry) % 10,而进位值为 (n1 + n2 + carry) / 10。

如果两个链表的长度不一致,那么就可以将短的链表所剩位置全设置为 0 。体现在代码中即:

int v1 = (l1 != null) ? l1.val : 0;
int v2 = (l2 != null) ? l2.val : 0;

最后,当链表遍历完成后,有 carry > 0 的情况,说明需要在结果链表的最后再附加一个节点,节点值为 carry,体现在代码中如下:

curr.next = new ListNode(carry);

计算结束,返回链表,直接返回虚拟头节点的next即可

return dummy.next;

完整代码如下:

/**
 * 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 dummy = new ListNode();
        ListNode curr = dummy;
        int carry = 0;

        while(l1 != null || l2 != null){
            int v1 = (l1 != null) ? l1.val : 0;
            int v2 = (l2 != null) ? l2.val : 0;
            int sum = v1 + v2 + carry;
            curr.next = new ListNode(sum % 10);
            carry = sum / 10;
            curr = curr.next;
            if(l1 != null){
                l1 = l1.next;
            }
            if(l2 != null){
                l2 = l2.next;
            }   
        }
        if(carry > 0){
            curr.next = new ListNode(carry);
        }
        return dummy.next;

    }
}

时间复杂度为 O(max(m, n)),其中 m 和 n 分别是两个链表的长度。

Categories:

Tags:

No responses yet

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注