难度:中等
给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例: 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
该题难度已经为我们降低了,因为已经为我们翻转了链表,是逆序计算的。但我们要注意几种特殊情况:
- 需要考虑的几种特殊情况
所以,为了避免以上几种特殊情况不能顺利通过,我们希望的是两个链表的长度一样长,就更加容易计算了。所以,我们在循环里时,先让两个列表对齐,空位置部分补零,然后再逐位计算。
但进行逐位计算的时候,我们要注意进位数的值,这个值,我们给
的初值为
,但是如果相加和为大于等于
的值的时候,
就被置为
。
最后,要考虑最后末尾的进位问题,进行一次判断,如果和
都到了最后一位还需要进位的话,就在最后再新建一个值为
的结点。
方法一:(补齐链表,数学计算法)
/**
* 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) {
int carry = 0; //设置进位
ListNode result = l1; //
while(l2!=null){
if(l1.next == null && l2.next!=null){
//如果l1没有l2长,那么l1补0
l1.next = new ListNode(0);
}
if(l2.next == null && l1.next!=null){
//如果l2没有l1长,那么l2补0
l2.next = new ListNode(0);
}
l1.val = carry + l1.val + l2.val;
//进位的计算
if(l1.val/10>0)
carry = 1;
else
carry = 0;
//末尾进位的处理
if(l1.val/10>0 && l1.next==null && l2.next==null)
l1.next = new ListNode(1);
l1.val = l1.val%10;
l1 = l1.next;
l2 = l2.next;
}
return result;
}
}
复杂度分析:
-
时间复杂度:
,假设
和
分别表示
和
的长度,上面的算法最多重复
次。
-
空间复杂度:
,新列表的长度最多为
-
Leetcode官方给出的题解:https://leetcode-cn.com/problems/add-two-numbers/solution/liang-shu-xiang-jia-by-leetcode/
可供大家参考