Leetcode之两数相加

1,960 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情

纠结了许久,力扣的学习终于开始了。。不过与其说纠结倒不如说是我真的好懒,本来想啃啃设计模式。然而只更了一篇便被劝退了,没有太多见解也只是学习的我感觉也确实不知道怎去写,也不知道怎么能去让别人知道我要传达什么,可能就是我懂得太少,书读的太少,希望接下来的日子不管每天收获是多是少,都要有收获。希望我自己可以坚持下来实现这个小小的flag。。。加油!

题目

两个非空链表,表示非负整数(都不会以0开头)。每位数字按逆序存储,每个节点只存储一位。将两数相加以相同形式返回一个表示和的链表。 示例

addtwonumber1.jpg

输入: l1 = [2,4,3], l2 = [5,6,4]
输出: [7,0,8]
解释: 342 + 465 = 807.

本题难点:处理进位

题解

前提:上图中从左到右表示的是个位、十位、百位。每个节点最大只能到9,如果超过9则需要进行进位处理。

思路:定义是否需要进位的变量let carry = 0;。数据相加会返回一个新的链表,这时需要在链表前创建一个dummy节点作为头部,相加之后的节点要往头部去穿。

sum.png

上图表示相同位相加,如果小于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;
};