LeetCode刷题挑战第二题- 两数相加(JS-中等)

303 阅读2分钟

题目

两数相加(难度-中等)>>

给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例

image.png

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

提示:

  • 每个链表中的节点数在范围 [1, 100] 内
  • 0 <= Node.val <= 9
  • 题目数据保证列表表示的数字不含前导零。

解答

题解:

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function(l1, l2) {
    let newListNode = new ListNode(0); //创建一个新的链表记录累加过的新链表
    let current = newListNode; //记录当前循环列加结果的个位数
    let carry = 0;//记录当前次循环的进位
    while(l1 || l2){
        let sum = 0;//记录当前次循环累加的值
        //每次循环l1,l2分别累加到sum中,然后分别都指向下一个节点,
        //直到指向链表的最后一个节点为null
        if(l1){
            sum += l1.val;
            l1 = l1.next;//
        }
        if(l2){
            sum += l2.val;
            l2 = l2.next;
        }
        
        //每次循环的结果记得加上进位
        sum += carry;
        //下一个节点的值为当前循环累加和的个位数,所以需要取模(余数)
        current.next = new ListNode(sum % 10); 
        //重新计算进位,即累加值的取整,因为两数相加肯定是两位数,直接除以10
        carry = Math.floor(sum/10); 
        //即将进入下次循环,循环的值指向下一个节点
        current = current.next; 
        
        //如果存在进位,那么新增下一个节点等于当前进位
        if(carry > 0){
         /**
         *这里另一层含义,
         *开头current = newListNode;current和newListNode指向同一个内存地址,所以返回newListNode
         */
            current.next = new ListNode(carry);
        }
    }
    
    /**
    *看此处,为什么返回的是newListNode.next,而不是newListNode。
    *我们上面let newListNode = new ListNode(0);此时newListNode=[0],
    *所以应该从第二个节点开始才是累加过的
    */
    return newListNode.next;
};

解题思路:

闲扯中。。。👉👉👉

看到题目,有点懵👀(逆序数字存储,每个节点存储一位??)看到给出的实例解释:342 + 465 = 807.,哦~~~ 恍然明白了,所以,第一个思路是什么??😁数组逆序求和再逆序回来。。。笑哭,这不是算法吧!!!

看题,题中给到的是链表,编辑区域中还直接写了Definition for singly-linked list.,所以链表是什么?

链表数据结构在后端语言中都有封装,像c,java,php等中,链表都是一种基本数据结构,在JavaScript中并没有封装链表,这又是为什么呢?简单的说,JS中的数组已经很灵活了。但是,链表还是有独有的优势,链表的插入/删除效率较高。

链表是什么?

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。 src=http___www.pianshen.com_images_359_1f6e696a2c3920b09785161fa7631d47.png&refer=http___www.pianshen.jpg

链表的head指向第一个元素,.next作为指针指向下一个元素。最后一个元素指向null。LeetCode编辑区域实际上已经帮我们默认的创建了链表ListNode,并且提示中也有给出Node.val存储了当前节点的值。

闲扯结束!!!👇👇👇

代码中的备注足够详细了,此处只贴图帮助理解。

image.png

提交结果执行用时内存消耗语言
通过88 ms45.8 MBJavaScript

复杂度分析:

  • 时间复杂度:O(max(m,n)),其中 m 和 n 分别为l1、l2链表的长度。我们要遍历两个链表的全部位置,而处理每个位置只需要 O(1) 的时间。
  • 空间复杂度:O(1)。注意返回值不计入空间复杂度。