難度:中等
給出兩個非空的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照逆序的方式存儲的,并且它們的每個節點只能存儲一位數字。
如果,我們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。
您可以假設除了數字 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/
可供大家參考