力扣100——两数之和
题目
本例是力扣当中一道中等难度的算法题:给你两个 非空 的链表,它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。这是一道链表题。在关于链表题的解法当中,递归占据了很大一部分解法,今天我们使用迭代的方法来求解。
解题方法
本题的主要难点在于进位,当两个数相加大于9的时候,我们就需要对其进行进位操作,而下一位同样要考虑进位,我们使用变量carry
来保存进位数据。其次,题目要求我们返回的是一个相加和的链表,并且是逆序的,所以我们需要定义一个链表List
。之后,我们需要对两个链表同时进行遍历,将遍历的和存储起来,并且处理进位。当两个链表长度不一致的时候,我们需要对其进行单独的处理,将其与前面的结果链接起来。
最后都处理完成,我们需要判断是否还有进位,如果有进位,我们需要将进位的数据添加到链表最底端。
代码
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var addTwoNumbers = function(l1, l2) {
// 保存进位信息
let carry = 0;
// 定义链表
function List() {
// 值
this.val = null;
// 下一个节点
this.next = null;
}
// 创建和链表
let list = new List();
// 创建一个变量,指向链表的头部
let head = list;
// 对两个链表进行遍历
while (l1 != null && l2 != null) {
// 判断两个链表的节点相加是否大于9,大于9则需要进位
if (parseInt(l1.val) + parseInt(l2.val) + carry > 9) {
// 需要进位,将两个链表的和加上进位变量去余数
head.val = (parseInt(l1.val) + parseInt(l2.val) + carry) % 10;
// 将进位信息存储起来
carry = 1;
// 两个链表同时后移
l1 = l1.next;
l2 = l2.next;
} else {
// 如何两个链表节点相加不大于9,则直接相加
head.val = (parseInt(l1.val) + parseInt(l2.val) + carry);
// 进位信息等于0
carry = 0;
// 两个链表同时后移一位
l1 = l1.next;
l2 = l2.next;
}
// 判断当前链表是否已经到了末尾
if(l1 != null || l2 != null || carry){
head.next = new List();
head = head.next;
}
}
// 判断链表l1是否遍历完成
while (l1 != null && l2 === null) {
// 判断链表的节点和进位信息相加是否大于9,大于9则需要进位
if((parseInt(l1.val) + carry) > 9){
head.val = (parseInt(l1.val) + carry) % 10;
carry = 1;
l1 = l1.next;
}else{
// 不i大于9则直接赋值
head.val = (parseInt(l1.val) + carry);
carry = 0;
l1 = l1.next;
}
if(l1 != null || carry){
head.next = new List();
head = head.next;
}
}
// 判断链表l2是否遍历完成
while (l1 == null && l2 !== null) {
if((parseInt(l2.val) + carry) > 9){
head.val = (parseInt(l2.val) + carry) % 10;
carry = 1;
l2 = l2.next;
}else{
head.val = (parseInt(l2.val) + carry);
carry = 0;
l2 = l2.next;
}
if(l2 != null || carry){
head.next = new List();
head = head.next;
}
}
// 判断进位信息是否还有值,有的话就加上去
if(carry){
head.val = carry;
}
return list;
};