给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head = null, tail = null;
int carry = 0;
while (l1 != null || l2 != null) {
int n1 = l1 != null ? l1.val : 0;
int n2 = l2 != null ? l2.val : 0;
int sum = n1 + n2 + carry;
if (head == null) {
head = tail = new ListNode(sum % 10);
} else {
tail.next = new ListNode(sum % 10);
tail = tail.next;
}
carry = sum / 10;
if (l1 != null) {
l1 = l1.next;
}
if (l2 != null) {
l2 = l2.next;
}
}
if (carry > 0) {
tail.next = new ListNode(carry);
}
return head;
}
}
作者:力扣官方题解
链接:https://leetcode.cn/problems/add-two-numbers/solutions/435246/liang-shu-xiang-jia-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这个是力扣的官方答案,这里附上相应的解析
- 初始化变量:
head
和tail
分别用来指向结果链表的头结点和尾结点。开始时,它们都是null
。carry
用来表示进位,初始化为0。
- 遍历链表:
- 使用
while
循环遍历l1
和l2
链表。只要l1
或l2
中有一个不为null
,就继续循环。
- 使用
- 处理当前位的值:
- 对于
l1
和l2
的当前节点,如果它们不为null
,则取它们的值;否则,取0(这用于处理链表长度不同的情况)。 - 计算当前位的和
sum
,它是n1
、n2
和carry
的和。
- 对于
- 构建结果链表:
- 如果
head
是null
(即结果链表为空),则创建一个新节点,并将其设置为head
和tail
。 - 如果
head
不是null
(即结果链表已有节点),则在tail
后面添加一个新节点,并更新tail
为这个新节点。 - 新节点的值是
sum % 10
,即当前位的和取模10后的结果。
- 如果
- 更新进位和链表指针:
- 更新
carry
为sum / 10
,即当前位的和的十位数,作为下一次循环的进位。 - 如果
l1
不为null
,则移动到下一个节点。 - 如果
l2
不为null
,则移动到下一个节点。
- 更新
- 处理最后的进位:
- 如果循环结束后
carry
仍然大于0,说明最高位有进位,需要在结果链表的最后添加一个值为carry
的新节点。
- 如果循环结束后
- 返回结果:
- 返回
head
,即结果链表的头结点。
- 返回
这段代码的时间复杂度是 O(max(m, n)),其中 m 和 n 分别是两个输入链表 l1
和 l2
的长度。这是因为我们需要遍历这两个链表的所有节点来计算它们的和。空间复杂度也是 O(max(m, n)),因为最坏情况下,结果链表的长度可能等于两个输入链表长度的较大值,再加上可能的一个额外的进位节点。