题目描述
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 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]
提示:
链表的长度范围为 [1, 100] 0 <= node.val <= 9 输入数据保证链表代表的数字无前导 0
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ad… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解思路
- 本体就是把两个链表的尾部开始看做两个数的个位,依次向前是十位,百位,千位...
- 由于链表是从头部开始,但计算应该从尾部开始做相加并且,满10要进位。
- 我们从各位开始计算就需要先将两个链表翻转,然后逐位相加。
- 最后将计算结果再次反转即为答案。
题解代码
* @lc app=leetcode.cn id=445 lang=javascript
*
* [445] 两数相加 II
*/
// @lc code=start
/**
* 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 reverseList = function(head){
let pre = null,cur = head;
while (cur) {
let next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
var addTwoNumbers = function(l1, l2) {
//如果有一个链表是0,相加之后必为另一个链表的值
if(l1.val === 0) return l2;
if(l2.val === 0) return l1;
//将两个链表反转
let revL1 = reverseList(l1),revL2 = reverseList(l2);
let sumList = new ListNode(0);//定义一个头结点为0的新链表
let sumNode = sumList;//新链表的头结点
let carry = 0;//进位标志
while(revL1 || revL2){
//使两个链表从个位开始相加,并加上进位的数值
let sum = (revL1 === null? 0 : revL1.val) + (revL2 === null? 0 : revL2.val) + carry;
//相加后如果值满10则进位,且该位应为-10之后的值
if(sum >= 10){
carry = 1;
sum -= 10;
}else{
carry = 0;
}
let newNode = new ListNode(sum);
sumNode.next = newNode;//使新链表的下一个值指向当前计算后的值
sumNode = sumNode.next;//指针移动到下一个节点
revL1 = revL1 == null ? null : revL1.next;
revL2 = revL2 == null ? null : revL2.next;
}
//循环完成后如果进位为1说明最高位满10
//此时需要添加最高位1
if(carry > 0) sumNode.next = new ListNode(carry);
//由于新链表头为0,所以从sumList.next开始才是计算后的值
//由于此时链表为反向的,所以需要再次反转链表才是最终结果
return reverseList(sumList.next)
};
// @lc code=end