一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情。
纠结了许久,力扣的学习终于开始了。。不过与其说纠结倒不如说是我真的好懒,本来想啃啃设计模式。然而只更了一篇便被劝退了,没有太多见解也只是学习的我感觉也确实不知道怎去写,也不知道怎么能去让别人知道我要传达什么,可能就是我懂得太少,书读的太少,希望接下来的日子不管每天收获是多是少,都要有收获。希望我自己可以坚持下来实现这个小小的flag。。。加油!
题目
两个非空链表,表示非负整数(都不会以0开头)。每位数字按逆序存储,每个节点只存储一位。将两数相加以相同形式返回一个表示和的链表。 示例
输入: l1 = [2,4,3], l2 = [5,6,4]
输出: [7,0,8]
解释: 342 + 465 = 807.
本题难点:处理进位
题解
前提:上图中从左到右表示的是个位、十位、百位。每个节点最大只能到9,如果超过9则需要进行进位处理。
思路:定义是否需要进位的变量let carry = 0;。数据相加会返回一个新的链表,这时需要在链表前创建一个dummy节点作为头部,相加之后的节点要往头部去穿。
上图表示相同位相加,如果小于10则直接赋值此节点。如果大于10,则需要将余数赋值给此节点再将进位数与下一节点之和相加。
① 如果位数不同时将最后一位直接赋值给新节点即可,这时还需要看有没有进位数,如果有进位数需要将进位数加进去。
② 当最后两位数相加大于10时还需要重复一遍下图②解释中的操作,最后将carry的值添加至末尾。
上图中①标处解释:相加之后的结果需要一个个向dummy节点后面串起来。
图中②解释:如果相加小于10,则直接相加。大于10,则需要下列两步计算 和:sum
1、 利用 sum % 10 取出余数作为链表中的数curr;
2、用Math.floor(sum / 10)取出整数赋值给carry作为是否存在进位;
在这其中每一步都要遍历carry是否为1,如果为1则下一节点和与其相加之后将其设置为0。最后返回dummy的next。
代码题解
var addTwoNumbers = function(l1, l2) {
let dummy = new ListNode(); // 用来占位,方便其返回头部
let curr = dummy; // 用来遍历链表,首次指向dummy (指单个相加之后的节点)
let carry = 0; // 处理进位的变量
while (l1 !== null || l2 !== null) { // 只要l1和l2其中有一个不为空,则需要计算和sum的值
let sum = 0;
if (l1 !== null) {
sum += l1.val; // 加上l1的值
l1 = l1.next; // l1需要进一位,不然则永远只读一个值
}
// 下面的l2则同上
if (l2 !== null) {
sum += l2.val;
l2 = l2.next;
}
// 下面需要检查carry的值看是否发生进位
sum += carry;
// 最后把这个新的值生成一个节点,贴在curr的后面
curr.next = new ListNode(sum % 10);
carry = Math.floor(sum / 10);
curr = curr.next; // 将节点移至下一位
}
// 最后还需检查一遍carry的值
if (carry > 0) {
curr.next = new ListNode(carry);
}
return dummy.next;
};