
思路分析:两个链表中节点数据倒序存储,但是两个链表左端对齐后,同一位置的数字可以直接相加,进位 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 分别是两个链表的长度。

No responses yet