28.两数相加(学习)
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例 2:
输入:l1 = [0], l2 = [0]
输出:[0]
示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]
提示:
每个链表中的节点数在范围 [1, 100] 内
0 <= Node.val <= 9
题目数据保证列表表示的数字不含前导零
解析:
一、初始化:
1.dummy是一个哑节点,它不包含实际的数据,但可以帮助我们方便地处理链表的头部。
2.current用于在构建结果链表时遍历和添加新节点。
3.carry用于存储加法运算中的进位。
二、遍历和计算:
1.计算当前位的和:首先,我们将carry(前一步的进位)加到sum中。然后,如果l1或l2不为空,我们将其节点的值加到sum中,并移动相应的指针到下一个节点。
2.更新进位:通过Math.floor(sum / 10)计算新的进位,这实际上是取sum除以10的整数部分。
3.创建新节点:通过new ListNode(sum % 10)创建一个新节点,该节点的值为sum除以10的余数,即当前位的值。
4.将新节点添加到结果链表中:通过current.next = …将新节点添加到结果链表的末尾,并更新current指针以便下一步操作。
三、处理剩余的进位:
1.在遍历完l1和l2之后,如果carry仍然大于0,说明最高位有进位,我们需要将这个进位作为一个新的节点添加到结果链表的末尾。
四、返回结果:
1.由于我们使用了哑节点,因此返回的是哑节点的下一个节点,即实际结果链表的头节点。
var addTwoNumbers = function(l1, l2) {
let dummy = new ListNode(0); // 使用哑节点来简化操作
let current = dummy;
let carry = 0; // 初始化进位为0
while (l1 || l2) {
let sum = carry; // 当前位的和初始化为进位值
if (l1) {
sum += l1.val;
l1 = l1.next;
}
if (l2) {
sum += l2.val;
l2 = l2.next;
}
carry = Math.floor(sum / 10); // 更新进位
current.next = new ListNode(sum % 10); // 创建新节点存储当前位的值
current = current.next; // 移动指针
}
if (carry > 0) {
// 如果循环结束后还有进位,则创建一个新的节点存储进位值
current.next = new ListNode(carry);
}
return dummy.next; // 返回哑节点的下一个节点,即新链表的头节点
};