题目描述:
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出: [8,9,9,9,0,0,0,1]
解题:
解释,该题即正常将链表中的值相应的加起来,例如
- l1:9 9 9 9 9 9 9
- l2:9 9 9 9
- rs:8 9 9 9 0 0 0 1
不要和正常的加法联想后干扰思路。
- 9 9 9 9 9 9 9
- 0 0 0 9 9 9 9
- 1 0 0 0 9 9 8
关键:8->9->9->9->0->0->0->1,将它想象成链表结构,最后返回的时候也是从头开始返回即可。
所以这里我们适合用双指针的思路:
- 一个指针
currL1指向l1。 - 一个指针
currL2指向l2。 - 一个新的链表
res保存这两个指针值相加的结果。 - 为了方便后续按顺序输出这个
res,我们需要一个新的指针curr来做累加时改变res的指针指向。 - (重点)因为涉及到进位
- 两个数是(0~9)范围,取他们的和余数放在结果中(
sum % 10) - 得到进位
sum / 10,让下一次的两个指针相加时带上这个进位,为了通用性,就需要初始时让进位数等于0,这样每次的操作都是相同的了。
- 两个数是(0~9)范围,取他们的和余数放在结果中(
- 如果最后还进位了,也就是l1和l2的指针都为null了,此时还有进位数存在,这时候需要让
curr在某位时在开辟一块空间直接存储这个进位就可。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
// 双指针的思路
ListNode currL1 = l1;
ListNode currL2 = l2;
// 保存结果
ListNode res = new ListNode(0);
// 做每一位的累加,并放在res中
ListNode curr = res;
// 进位
int up = 0;
while(currL1 != null || currL2 != null){
int l1Value = currL1 != null ? currL1.val:0;
int l2Value = currL2 != null ? currL2.val:0;
int sum = l1Value + l2Value + up;
// 进位
up = sum / 10;
// 余数留下
curr.next = new ListNode(sum % 10);
curr = curr.next;
if(currL1 != null)currL1 = currL1.next;
if(currL2 != null)currL2 = currL2.next;
}
// 如果余数还存在,直接将其值放在尾部
if(up != 0){
curr.next = new ListNode(up);
}
return res.next;
}
}