题目
给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例
输入: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中的数组已经很灵活了。但是,链表还是有独有的优势,链表的插入/删除效率较高。
链表是什么?
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
链表的head指向第一个元素,.next作为指针指向下一个元素。最后一个元素指向null。LeetCode编辑区域实际上已经帮我们默认的创建了链表ListNode,并且提示中也有给出Node.val存储了当前节点的值。
闲扯结束!!!👇👇👇
代码中的备注足够详细了,此处只贴图帮助理解。
| 提交结果 | 执行用时 | 内存消耗 | 语言 |
|---|---|---|---|
| 通过 | 88 ms | 45.8 MB | JavaScript |
复杂度分析:
- 时间复杂度:O(max(m,n)),其中 m 和 n 分别为l1、l2链表的长度。我们要遍历两个链表的全部位置,而处理每个位置只需要 O(1) 的时间。
- 空间复杂度:O(1)。注意返回值不计入空间复杂度。