给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807
这里leetcode给我们限定的数据结构如下:
class ListNode{
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
2 -> 4 -> 3 + 5 -> 6 -> 4 两个链表长度都一样,计算也比较简单,从左向右依次计算,即l1、l2的第一位相加,l1、l2第二位相加,如果计算结果大于10,则当前位取模(sum%10),计算下一位时需在两数相加结果的前提下+1。这里需考虑如下三种情况:
- l1长度等于l2
- l1长度大于l2
- l1长度小于l2
有了前面的逻辑,下面是我实现的代码,该代码还有很多可以改进的地方,但是不影响整体逻辑:
/**
* 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 nodeList1 = l1;
ListNode nodeList2 = l2;
ListNode firstNode = nodeList1;
boolean first = true;
// 判断前面一个数是否>10,否则近一
boolean flag = false;
// 相加后的值对10取余
int digit = 0;
while (nodeList1.next != null && nodeList2.next != null) {
if (flag) {
digit = nodeList1.val + nodeList2.val + 1;
flag = false;
} else {
digit = nodeList1.val + nodeList2.val;
}
if (digit >= 10) {
flag = true;
}
digit = digit % 10;
// 将计算后的值放入nodeList1中
nodeList1.val = digit;
if (first) {
first = false;
}
// 迭代
nodeList1 = nodeList1.next;
nodeList2 = nodeList2.next;
}
// 确定链表最后一个元素不被忽略
if (flag) {
digit = nodeList1.val + nodeList2.val + 1;
flag = false;
} else {
digit = nodeList1.val + nodeList2.val;
}
if (digit >= 10) {
flag = true;
}
digit = digit % 10;
// 将计算后的值放入nodeList1中
nodeList1.val = digit;
if (nodeList1.next != null) { // l1 > l2
nodeList1 = nodeList1.next;
// 如果l1、l2对齐的最后一位之和大于10,这里人要对l1下一位近一
// 如果输入为l1[9,9], l2[9]时,该逻辑会出错
while (nodeList1.next != null) {
if (flag) {
nodeList1.val = nodeList1.val + 1;
flag = false;
}
if (nodeList1.val >= 10) {
nodeList1.val = nodeList1.val % 10;
flag = true;
}
nodeList1 = nodeList1.next;
}
if (flag) {
nodeList1.val = nodeList1.val + 1;
if (nodeList1.val >= 10) {
nodeList1.val = nodeList1.val % 10;
nodeList1.next = new ListNode(1);
}
}
} else if (nodeList2.next != null) { // l1 < l2,将l2链表追加到l1上
nodeList2 = nodeList2.next;
nodeList1.next = nodeList2;
while (nodeList2.next != null) {
if (flag) {
nodeList2.val = nodeList2.val + 1;
flag = false;
}
if (nodeList2.val >= 10) {
nodeList2.val = nodeList2.val % 10;
flag = true;
}
nodeList2 = nodeList2.next;
}
if (flag) {
nodeList2.val = nodeList2.val + 1;
// l1[1],l2[9, 9] ==> 0-0-1
if (nodeList2.val >= 10) {
nodeList2.val = nodeList2.val % 10;
nodeList2.next = new ListNode(1);
}
}
} else { // l1 == l2,如果l1、l2两个元素均为5,则还需计算下一位,否则直接返回firstNode即可
if (flag) {
// 此时nodeList1下一位肯定是null,这里需要重新构建一个新的ListNode以重新构建链表
nodeList1.next = new ListNode(0);
nodeList1 = nodeList1.next;
nodeList1.val = nodeList1.val + 1;
}
}
// l1 == l2 则直接返回firstNode即可
return firstNode;
}
}
该开始提交上去一直报错,原因是由于很多极值情况未考虑到,如[0],[0]、[5],[5]、[9],[9,9]等,不过补充完后也能正常运行,后来发现打败了全国14%的用户,真的好忏愧,不过上面代码还是有很多改进的地方,不过整体逻辑蛮清楚,可以提供很多参考。
这里是正确答案。