题目描述
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例1:
输入:l1 = [7,2,4,3], l2 = [5,6,4]
输出:[7,8,0,7]
示例2:
输入:l1 = [2,4,3], l2 = [5,6,4] 输出:[8,0,7]
示例3:
输入:l1 = [0], l2 = [0] 输出:[0]
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ad… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
我开始的想法比较暴力,直接把两个链表遍历,处理成数字,然后直接相加
- 比如6>7>4>2 就遍历,成number 6742 结果提交失败了,因为链表长度很大时候,不支持那么大位数的直接整数计算
然后大致思路还是这样,不过不用数字来存储了,直接用数组来存储两个链表的元素
- 再遍历两个数组同位数相加的值来作为新链表的节点值
- 这里有几个点注意
- 由于数字是从最后一位开始加的,且两个链表长短不一,所以存的时候倒过来存,最后的位数放最前面,遍历的时候从头遍历就能实现从尾部相加
- 相加可能超过10的情况需要特殊处理往后一位进1
代码
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var addTwoNumbers = function(l1, l2) {
let num1=[];//保存第一个链表转化成的数字
let num2=[];//保存第二个链表转化成的数字
while(l1){
//遍历,每个数字作为之前数字的位数,把之前数字乘以10再加自己,就能实现
num1.unshift(parseInt(l1.val));//因为相加时候是从尾部加,而且两个链表长度不一,所以倒过来,添加,相加的时候正向遍历就相当于从位数相加了,最后生成节点再倒出来就行
l1=l1.next;
}
while(l2){
//同上
num2.unshift(parseInt(l2.val));
l2 = l2.next;
}
let n=num1.length>num2.length?num1.length:num2.length;//判断谁位数长,以长的作为遍历的数量
let newHead=null;//新链表
let pre=0;//储存前一位,超过10的位数,需要加到高位上
for(let i=0;i<n;i++){
let total=(num1[i]?num1[i]:0)+(num2[i]?num2[i]:0)+pre;//同位相加
if(total>=10){
pre =1;//因为个位数相加最多不超过18,所以超过一定是1;
total-=10;
}else{
pre=0;
}
let node=new ListNode(total,null);
node.next=newHead;
newHead=node;//因为前面把位数反过来了,所以现在把位数返回去,越后面的节点位数越高,所以放到链表头部就行
if(pre===1&i===n-1){
//如果是最后一个数由于,后面没有数字进来了,所以进的1要直接添加
let last=new ListNode(1,null);
last.next=newHead;
newHead=last;//因为前面把位数反过来了,所以现在把位数返回去,越后面的节点位数越高,所以放到链表头部就行
}
}
return newHead;
};