给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
注意点:两个链表长度是不定的。
收获的知识点:更加通透的理解了链表,之前只是知道一个数据有next,value属性。但是不理解链表这种结构是怎么定义的。于是乎,终于理解了。
从最开始讲起,这个就是链表的存储结构。定义了val,next属性。
function ListNode(val) {
this.val = val;
this.next = null;
}
链表的存储结构从这里也可以看出,是一个对象的next属性值下一个对象。当然从存储位置来说,他们存储不是连续的。
题目给出来的参数l1
和l2
就是一个链表的头节点,通过next
可以不断向下访问。
var addTwoNumbers = function(l1, l2) {
那如果要在链表上添加元素,通过他的构造函数,先构建一个节点new ListNode
。比如说往l1
添加节点。l1.next = new ListNode
理解完这个以后,就可以正式开始这道编程题了。
思路曾经弯弯绕绕,因为很久都没看过链表的增删改了。导致很失忆
首先肯定有res
这个输出结果的对象。
当我们添加元素时,通过一个指针p
移动来进行增删改。先让他等于第一个节点p=res
为什么指针移动就能对res增删改呢?我的理解是,因为这个=赋值,其实p,res都是同一处对象,通过p指针创建下一个节点,然后保留res这个头节点,便于访问。他们都是同一个链表。
然后就是几个要考虑的情况:
①当一个链表已经遍历到头了,另一个链表还可以继续遍历,应该怎么操作?
②当两个链表都完成遍历,但是最后一位产生了进位,怎么操作?
我觉得这个答案写的还挺优雅的
var addTwoNumbers = function(l1, l2) {
let addtonext = 0
let res = new ListNode()
let p = res
let ll1=l1
let ll2=l2
while(ll1|| ll2){
let x = ll1!=null ? ll1.val:0
let y = ll2!=null ? ll2.val:0
let tempres = x + y + addtonext
addtonext = tempres >= 10 ? 1 : 0
p.next = new ListNode(tempres % 10)
p=p.next
if(ll1) ll1=ll1.next
if(ll2) ll2=ll2.next
}
if(addtonext!=0) p.next = new ListNode(addtonext)
return res.next
}
分析:这个答案采用了一个哑节点。就是平时的思路是。第一次赋值直接p.val= ...
,但是这里是空出了这个节点,有什么好处呢?
如果不使用哑节点,就是这样。我本来也是这么写的
但是这么写的话,就会有问题。l1,l2遍历完,结果会多一个节点。然后你就要写if语句,去限制他各种情况,在while循环中,写if语句消耗挺大,使得我的代码始终无法在时间内运行。
总结完毕。