入门版(2题)
题目描述
解题思路:迭代 + dummy node
在给定的链表中,数字所在的位数随着链表前进方向而变高
因此,在每一轮迭代中:
- 计算相同位置上的两数相加之和 res
- 根据res得出进位cin为0或1
- res对10取余后,放进新节点中
- 令 上一个节点(prev)的next 指向当前的新节点
- prev指向当前节点
直到两个链表都遍历结束,迭代完成
除此之外,还需要注意两点:
- 在新链表的第一个节点产生之前,需要构造一个虚拟节点(dummy node),用于最后返回结果
- 迭代结束后,还要检查进位
代码实现(Javascript)
var addTwoNumbers = function(l1, l2) {
var p1 = l1
var p2 = l2
var cin = 0
var prev = new ListNode(-1,null)
var preHead = prev
while(true){
let res
if(!p1 && !p2) { //p1和p2都空
break
}else if(!p1 && p2) { // p1空,p2非空
res = p2.val + cin
p1 = null
p2 = p2.next
}else if(p1 && !p2) { // p1非空,p2空
res = p1.val + cin
p2 = null
p1 = p1.next
}else {
res = p1.val + p2.val + cin
p1 = p1.next
p2 = p2.next
}
if(res <= 9){
cur = new ListNode(res,null)
cin = 0
}else {
cur = new ListNode(res % 10,null)
cin = 1
}
prev.next = cur
prev = cur
}
if(cin!==0){
cur = new ListNode(cin,null)
prev.next = cur
}
return preHead.next
};
进阶版(445题)
题目描述
解题思路1:反转链表 + 两数相加
在这道题中,数字最高位是位于链表开始位置的,这意味着我们不能沿着链表的前进方向 来进行数字的相加
我们可以先将两个链表进行反转,然后将结果传入上一题写好的函数中,最后再返回反转的链表
反转链表的函数:
var reverseList = function(head) {
if(!head){
return null
}
if(!head.next){
return head
}
var cur = head
var pre = head.next
var temp = null
cur.next = null
while(pre){
temp = pre.next
pre.next = cur
cur = pre
pre = temp
}
return cur
};
上一题的函数(命名为 add)
略:详见上一题的解析
主函数:
var addTwoNumbers = function(l1, l2) {
var newL1 = reverseList(l1)
var newL2 = reverseList(l2)
var res = add(newL1,newL2)
return reverseList(res)
};
解题思路2:栈 + 迭代
我们可以先将两个链表的节点值 按顺序分别放入两个栈中
然后在每一轮迭代中:
- 分别取出2个栈的栈顶元素,加上进位carry,得到结果res
- 根据res,得出下一轮的进位carry值
- res对10取余后,放进新节点cur
- 让新节点(cur)的next 指向 上一个节点(prev)
- prev指向新节点
直到两个栈都为空,迭代结束
最后再检查进位carry即可
var addTwoNumbers = function(l1, l2) {
var s1 = new Array()
var s2 = new Array()
while(l1){
s1.unshift(l1.val)
l1 = l1.next
}
while(l2){
s2.unshift(l2.val)
l2 = l2.next
}
var prev = null
var carry = 0
var res
while(true){
if(s1.length > 0 && s2.length > 0){
res = s1.shift() + s2.shift() + carry
}else if(s1.length > 0 && s2.length === 0){
res = s1.shift() + carry
}else if(s2.length > 0 && s1.length === 0){
res = s2.shift() + carry
}else{
break
}
if(res <= 9){
carry = 0
}else{
carry = 1
}
let cur = new ListNode(res%10)
cur.next = prev
prev = cur
}
//检查最高位有无进位
if(carry === 1){
let high = new ListNode(carry)
high.next = prev
prev = high
}
return prev
};