题目:给出两个非空的链表,分别用来表示两个非负的整数。其中,它们各自的位数是按逆序的方式来存储的,并且它们的每个节点只能存储一位数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
可以假设这两个数都不会以0开头。
示例1:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
这是一个很标准的示例,两个链表中存储的都是三位数,这个示例看不出更多的信息,接下来我再写几个示例:
示例2:
输入:(2)+(8)
输出:0 -> 1
原因:2 + 8 = 10
示例3:
输入:(7)+(7 -> 9 -> 9)
输出:4 -> 0 -> 0 -> 1
原因:7 + 997 = 1004
从这两个示例中,我们可以看到实现代码的一些问题,如下:
思路:刚看到这道题的时候,我当时想创建一个新的链表用来存储这两个数相加的计算结果。但是,考虑到如果将进位存储到新链表,则新链表也需要参与运算,这稍微增加了一些复杂性(个人感觉)。而这两个数本身就是存储在两个链表中,如果用其中一个链表来存储结果并进行运算,就足够。
如果存储两个数的链表长度不一致,只需给短的链表补足即可。而进位产生新节点,则只会出现在两个数的最高位相加大于10的情况下,此时只要新增一个节点存储进位,并且让结果链表的最后一个节点的后继指针指向该新增节点即可。
以【示例3】为例,计算步骤如下图:
①、假设以存储数字7的链表L1来存储计算结果,原始状态如下:
②、逐位相加,对10取余,将取余结果存储到L1的当前参与计算的节点中,如下图:
③、因为L1缺少下层节点,则给其补一个节点,如下图:
④、因为当前计算结果是14,需要进位,所以让L1下一个节点进位,如下图:
⑤、重复②、③、④步骤,当结果如下图时:
则,L1和L2都没有后继节点,并且最后的节点之和等于10。此时,需要进位,因此新增一个节点,让L1最后一个节点指向新节点,如下图:
至此,【示例3】计算完成。如果是【示例1】那种标准的,最后不会产生进位的,则当两个链表没有后继节点时,即表示计算完成。
代码如下:
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int c = l1.val + l2.val;
l1.val = c % 10;
if (l1.next == null && l2.next == null) {
if (c > 9)
l1.next = new ListNode(1);
return l1;
}
if (l1.next == null) {
l1.next = new ListNode(0);
}
if (l2.next == null) {
l2.next = new ListNode(0);
}
if (c > 9) {
l1.next.val++;
}
ListNode next = addTwoNumbers(l1.next, l2.next);
l1.next = next;
return l1;
}
测试代码:
/**
* 反转ListNode链表
*
* @param pre
* @return
*/
public ListNode reverse(ListNode first) {
ListNode pre = first;
ListNode current = first.next;
pre.next = null;
while (current != null) {
ListNode next = current.next;
current.next = pre;
pre = current;
current = next;
}
return pre;
}
/**
* 将一个整数转换为ListNode链表
*
* @param n
* @return
*/
public ListNode int2ListNode(int n) {
ListNode node = new ListNode(n % 10);
ListNode tmp = node;
do {
n = n / 10;
if (n != 0) {
ListNode next = new ListNode(n % 10);
tmp.next = next;
tmp = next;
}
} while (n != 0);
return node;
}
public static void main(String[] args) {
AddTwoNumbers atn = new AddTwoNumbers();
ListNode l1 = atn.int2ListNode(876);
ListNode l2 = atn.int2ListNode(132);
ListNode result = atn.addTwoNumbers(l1, l2);
ListNode first = atn.reverse(result);
while (first != null) {
System.out.print(first.val);
first = first.next;
}
}
运行结果:1008
当然,我们还可以测试更多组合,比如:l1=997、l2=7,l1=876、l2=232,l1=7、l2=7等,运行结果都是正确的。
这是我在leetcode上面的第二道题,感觉还是有一些难度的,对于我这种老年人来说(^ _ ^),这个代码在leetcode是提交成功的:
因此,应该是没问题的,毕竟经过了leetcode数据集的检验。
最近,空闲的时候在刷leetcode,感觉脑子都不够用了,加油锻炼思维~~