给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
解法一
自己写的,没看题解,所以写得不好,我是先确定两条链表的长度,然后根据链表的长度进行编码的,做完之后看了题解,发现可以用递归做,而且只要确定两条链表的最后节点都为null即可,如果一条提前结束,那么就接上一个新节点,内容为0。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//因为题目说了是非空链表,所以我们从第2个节点开始循环
//首先,循环得出两条链表的长度
int len1 = 1, len2 = 1;
ListNode temp = l1;
while (temp.next != null) {
temp = temp.next;
len1++;
}
temp = l2;
while (temp.next != null) {
temp = temp.next;
len2++;
}
//保存l1的初始节点
temp = l1;
int num = 0;
//其中一条链表长度到1结束循环,得到两条链表的最后的节点
while (len1 > 1 && len2 > 1) {
l1.val = l1.val + l2.val + num;
num = 0;
if (l1.val >= 10) {
//因为个位数相加最大是18,所以num=1保存进1
num = 1;
l1.val %= 10;
}
l1 = l1.next;
l2 = l2.next;
len1--;
len2--;
}
//最后节点相加
l1.val = l1.val + l2.val + num;
num = 0;
if (l1.val >= 10) {
//因为个位数相加最大是18,所以num=1保存进1
num = 1;
l1.val %= 10;
}
//l1到最后节点而l2还没到
if (len1 == 1 && len2 != 1) {
l1.next = l2.next;
}
//如果拼接完后,num=1,那么循环进行相加,直到num=0
//防止99999,这种情况
while (num != 0) {
if (l1.next == null) l1.next = new ListNode(0);
l1 = l1.next;
l1.val += num;
num = 0;
if (l1.val >= 10) {
//因为个位数相加最大是18,所以num=1保存进1
num = 1;
l1.val %= 10;
}
}
return temp;
}
}
代码有点多,看起来挺乱的,因为是一点一点写出来的,提交错误就出现2次。
解法二
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
//递归相加
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode result = new ListNode(0);
add(result, l1, l2, 0);
return result;
}
private void add(ListNode result, ListNode l1, ListNode l2, int carry) {
//出口
if (l1 == null && l2 == null && carry == 0) return;
if (l1 == null) l1 = new ListNode(0);
if (l2 == null) l2 = new ListNode(0);
int num = l1.val + l2.val + carry;
carry = num / 10;
result.val = num % 10;
//如果一直递归的话,最后会多出一个节点,所以需要再这里再加一个判断
//如果满足条件就停止递归
if (l1.next == null && l2.next == null && carry == 0) return;
//递归
result.next = new ListNode(0);
add(result.next, l1.next, l2.next, carry);
}
}
很明显,用递归是比上一个解法好很多,内存消耗少,看起来也比较清晰。