一、两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
输入: l1 = [2,4,3], l2 = [5,6,4]
输出: [7,0,8]
解释: 342 + 465 = 807.
示例 2:
输入: l1 = [0], l2 = [0]
输出: [0]
示例 3:
输入: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出: [8,9,9,9,0,0,0,1]
提示:
- 每个链表中的节点数在范围
[1, 100]内 0 <= Node.val <= 9- 题目数据保证列表表示的数字不含前导零
二、解题思路:
1.迭代法
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int val=0, ListNode next=null) {
* this.val = val;
* this.next = next;
* }
* }
*/
public class Solution {
public ListNode AddTwoNumbers(ListNode l1, ListNode l2) {
//记录每次提取十位上数的值
int next1 = 0;
//记录每次要相加的数
int total = 0;
//创建一个新节点
ListNode dummy = new ListNode();
//新节点复制给另一个新节点,后续可以拿cur节点进行移动,而不动dummy节点,cur可以让我知道当前的指针是在哪
ListNode cur = dummy;
//循环遍历进行操作,当其中有一个链表走到头了我们就跳出循环
while (l1 != null && l2 != null) {
//total记录的是每次两数相加+每次两数相加之后有十位数的值要提取的值
total = l1.val + l2.val + next1;
//可移动节点的引用指向由个位数上的值所创建的链表节点,也就是把每次的个位数的值作为最终结果节点的每一项值
cur.next = new ListNode(total % 10);
//获取的是十位数上的值
next1 = total / 10;
//移动到下一个节点去
l1 = l1.next;
l2 = l2.next;
//当前可移动节点指向下一个可移动节点
cur = cur.next;
}
//判断l1是否走到头,如果没有,那就是l2走到头了
while (l1 != null) {
total = l1.val + next1;
cur.next = new ListNode(total % 10);
next1 = total / 10;
l1 = l1.next;
cur = cur.next;
}
//l2没有走完的情况下,同时l1走完了
while (l2 != null) {
total = l2.val + next1;
cur.next = new ListNode(total % 10);
next1 = total / 10;
l2 = l2.next;
cur = cur.next;
}
//next1==0,说明l1,l2都走完了,如果不等于0说明,此时还有一个数没有加进来,需要再次加入到链表中
if (next1 != 0) {
//创建一个新的节点,存储最后的十位数
cur.next = new ListNode(next1);
}
//注意返回的是节点的next
return dummy.next;
}
}
2.递归法
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int val=0, ListNode next=null) {
* this.val = val;
* this.next = next;
* }
* }
*/
public class Solution {
public ListNode AddTwoNumbers(ListNode l1, ListNode l2) {
//先记录两次节点的数之和
int total = l1.val + l2.val;
//记录十位数的值,后续要进位
int next1 = total / 10;
//以个位数上的值创建一个新链表节点
ListNode res = new ListNode(total%10);
//循环判断,l1,l2是否已经遍历完,或者next1是否为0,为0表示l1,l2同时走完,不为0表示某一个走完都有可能
if (l1.next != null || l2.next != null || next1 != 0) {
//下一个节点的指向不为null,则指向下一个节点,为null,则表示当前链表走完了,就以0位值创建一个新链表
l1 = l1.next!=null ? l1.next : new ListNode(0);
l2 = l2.next!=null ? l2.next : new ListNode(0);
//将每次需要提取的十位数加入l1链表当前项中,加入l2链表其实也是一样的
l1.val += next1;
//改变可移动链表的指向,每一次的调用,里面的l1,l2的值都会是下一项的值
res.next = AddTwoNumbers(l1, l2);
}
//直到两个链表都遍历完,返回链表
return res;
}
}