题目链接:力扣
这道理首先要明白一个leetcode的数据结构 - ListNode
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
ListNode其实就是数据结构的链表,这里大概讲解一下链表
链表 -
链表的定义:
链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
链表的结构特点:
头指针head和终端结点:
单链表中每个结点的存储地址是存放在其前趋结点next域中,而开始结点无前趋,故应设头指针head指向开始结点。链表由头指针唯一确定,单链表可以用头指针的名字来命名。
终端结点无后继,故终端结点的指针域为空,即NULL。
单链表示意图:
简单了解链表之后再看ListNode ,l1是一个listNode的头结点,也就是第一个结点,取值l1.val, 而l1.next指向的就算这链表的下一个结点
了解这些知识之后再来做题就简单了很多
var addTwoNumbers = function (l1, l2) {
let p1 = l1, p2 = l2;
//构建一个虚拟头结点
let dumy = new ListNode(-1);
//指针负责构建新链表
let p = dumy;
//记录进位
let carry = 0;
while(p1 != null || p2 != null || carry > 0) {
let sum = carry;
if(p1 != null) {
sum += p1.val;
//指向下一个结点
p1 = p1.next;
}
if(p2 != null) {
sum += p2.val;
//指向下一个结点
p2 = p2.next;
}
carry = Math.floor(sum / 10); //进位
sum = sum % 10; //当前位置数
p.next = new ListNode(sum);
p = p.next;
}
//返回头节点
return dumy.next
};
案例解析
l1 = [2,4,3], l2 = [5,6,4]
用图首先解析一下 - 对于加数大于10进1,需要用变量记录什么时候需要进位 - carry
对于加法,取出链表1和链表2对应个位的值相加,有进位,进位,无继续取下一个位进行相加
这是一个循环的过程,跳出循环的时机 ----- 所有位数加完或者没有进位的时候(如题,百位数都加完,且百位数已经没有进位就不用继续)
首先,返回的是一个链表的的头结点,因此第一步先定义一个链表
(1)-1是一个虚拟结点,他的第一个结点,dumy.next就是最后返回的结果,p是构建新的链表
let dumy = new ListNode(-1)
let p = dumy
(2)定义进位
let carry = 0
(3)参数了l1, l2,是一个链表的头结点,第一个值 (l1.val => 2, l2.val=> 5)
进行相加,第一位数 2 + 5 + 0 = 7;
新链表 新链表的第一位val = 7 , 进位 0;
取十位 4 + 6 + 0 = 10; 新链表第二位val = 0; 进位 1 ,循环