給定兩個非空的鏈表,表示兩個非負整數。 數字以相反的順序存儲,每個節點包含一個數字。 添加兩個數字並將其作爲鏈表返回。
可以假設兩個數字不包含任何前導零,除了數字0本身
舉例:
輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
分析:使用變量跟蹤進位,並從包含最低有效數字的列表頭開始模擬逐位數字和。
兩個相加數字的可視化:342 + 465 =807。
每個節點包含單個數字,數字以相反的順序存儲。
就如在紙上相加兩個數字一樣,我們先將最低有效位的數字相加,即l1和l2的頭部。由於每個數字都在0~9之間,所以兩個數字相加可能會導致“溢出”(例如5+7=12)。這時,我們將當前數字設爲2,並將carry=1移入下一次迭代。carry必須爲0或者1,兩位數最大的可能爲9+9+1(進位)=19,carry不可能爲2及以上的數字。
僞代碼如下:
- 將當前節點初始化爲返回列表的虛擬頭。
- 初始化進位(carry)爲0。
- 初始化p和q分別爲l1和l2的頭部。
- 循環l1和l2鏈表直到到達兩者的結尾。
(1). 將x設置爲節點p的值。 如果p已經達到l1的結尾,則設置爲0。
(2).將y設置爲節點q的值。 如果q已經達到l2的結尾,則設置爲0。
(3).設sum=x+y+carry.
(4).更新carry=sum/10.
(5).創建一個新的值爲(sum mod 10)的節點並且將其設置爲當前節點的下一個節點,然後將當前節點推進到下一個節點。
(6).將p和q移到下一個節點。 - 檢查進位carry是否爲1,如果是1將新的節點加1。
- 返回虛擬頭的下一個節點。
請注意,我們使用虛擬頭來簡化代碼。 沒有一個虛擬頭,你將不得不編寫額外的條件語句來初始化頭的值。
//java代碼
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(0);
ListNode p = l1, q = l2, curr = dummyHead;
int carry = 0;
while (p != null || q != null) {
int x = (p != null) ? p.val : 0;
int y = (q != null) ? q.val : 0;
int sum = carry + x + y;
carry = sum / 10;
curr.next = new ListNode(sum % 10);
curr = curr.next;
if (p != null) p = p.next;
if (q != null) q = q.next;
}
if (carry > 0) {
curr.next = new ListNode(carry);
}
return dummyHead.next;
}
/**
* c++代碼
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode c1 = l1;
ListNode c2 = l2;
ListNode sentinel = new ListNode(0);
ListNode d = sentinel;
int sum = 0;
while (c1 != null || c2 != null) {
sum /= 10;
if (c1 != null) {
sum += c1.val;
c1 = c1.next;
}
if (c2 != null) {
sum += c2.val;
c2 = c2.next;
}
d.next = new ListNode(sum % 10);
d = d.next;
}
if (sum / 10 == 1)
d.next = new ListNode(1);
return sentinel.next;
}
}
如有問題,歡迎批評指正。