题目
-
给出两个
非空
的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序
的方式存储的,并且它们的每个节点只能存储一位
数字。 -
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 您可以假设除了数字 0 之外,这两个数都不会以
0
开头。 -
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
分析
- 输入的是两个链表
- 链表的顺序是数字的倒序,且每个节点存一位数字
- 两个链表的长度不一定相同
- 输出的结果为两数相加后和的倒序
- 每个位相加后有可能进位即(l1.val + l2.val + param(进位值:0 | 1)),最小值(0 + 0 + 0),最大值(9 + 9 + 1)
解题思路
- 遍历两个链表,将相同的每个位置数相加后组成一个相加结果的倒序字符串;注意处理特殊情况,可以快速得到特殊情况的结果,例如:链表一或者链表二为空的情况;注意判断临界条件,例如:链表一或者链表二结束时
(list.next === null)
- 声明初始的变量
let x = l1, // 链表一的首位
y = l2, // 链表二的首位
param = 0, // 进位值
value = ''; // 结果字符串
- 判断特殊情况
if ( !l1 ) return l2
if ( !l2 ) return l1
- 同时循环两个链表
while(x || y) {
let xV = x ? x.val : 0; // 链表一是否结束,结束用0补位
let yV = y ? y.val : 0; // 链表二是否结束,结束用0补位
value += ( xV + yV + param) % 10 // 获取当前位的值
param = parseInt( ( xV + yV + param ) / 10, 10 ) // 获取进位值
if (x) x = x.next // 判断链表一是否结束
if (y) y = y.next // 判断链表二是否结束
}
- 循环完之后判断param进位是否位0,不为0,追加到value之后
if( param ) value += param
- 处理value,并返回目标结果
let node = { // 创建节点
val: null,
next: null
},
head = node;
value.split('').forEach(item => {
node.next = {
val: parseInt(item,10), // 字符串split后得到的是字符,所以需要转成数字number类型
next: null
}
node = node.next;
})
return head.next;
- 全部代码
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var addTwoNumbers = function(l1, l2) {
let x = l1,
y = l2,
param = 0, // 进位值
value = '';
if ( !l1 )return l2
if ( !l2 ) return l1
while(x || y) {
let xV = x ? x.val : 0;
let yV = y ? y.val : 0;
value += ( xV + yV + param) % 10
param = parseInt( ( xV + yV + param ) / 10, 10 )
if (x) x = x.next
if (y) y = y.next
}
if( param ) value += param
let node = {
val: null,
next: null
},
head = node;
value.split('').forEach(item => {
node.next = {
val: parseInt(item,10),
next: null
}
node = node.next;
})
return head.next;
};
总结
- 数字的操作,需要多考虑临界条件,相加的进位、相减的借位等等
- 链表的遍历,考虑是否为空,是否已到尾部
- 本题的解法不唯一,欢迎共同探讨学习