“
題目:
兩數相加
給出兩個 非空 的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式存儲的,並且它們的每個節點只能存儲 一位 數字。
如果,我們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。
您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。
示例:
輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
原因:342 + 465 = 807
### 解題思路
解題思路:比如 a+b
數字上考慮三種情況,是a先被遍歷完還是b先遍歷完,還是兩個一起先被遍歷完。
無論哪一種,都要考慮當前計算是否有進位帶來的影響:前兩種m,當心被被遍歷完的數字的最後參與運算的一個進位標誌,r如果存在進位,則後續沒被執行完的那個也要更新如:1+199=200; 最後一種情況,d即使兩個數字都結束了遍歷,也可能還有一個進位。比如:12+88=100;
我的錯誤過程:
1)沒有看到節點類型沒有默認構造函數,所以申請時候未給它初始化數值
2)沒有考慮到最後一個循環裏面while循環變量的更新,然後我發現我也沒考慮到申請的對於節點-1節點,恰好一起在最後一個while循環中改了。
3)p指針錯用free釋放,應用delete。
### 代碼
```cpp
/**
* Definition for singly-linked list.
* struct ListNode {//節點類型,無默認構造函數
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* l1ptr, *l2ptr, *l3ptr;//遍歷兩個輸入串的指針,遍歷結果串的指針
l1ptr = l1, l2ptr = l2;
ListNode* addNum = new ListNode(-1);
l3ptr = addNum;
int CarryFlag = 0, curAdd = 0;//進位標誌和當前數字和。
while (l1ptr != NULL&&l2ptr != NULL) {//兩個數字都沒被加完時
curAdd = l1ptr->val + l2ptr->val;
if (CarryFlag) curAdd++;//上一次若有進位則加進來
if (CarryFlag = curAdd/10) curAdd -= 10;//如果有k進位則更新進位,和當前數字和。
l3ptr->val = curAdd;//第三鏈表指針更新
l3ptr->next = new ListNode(-1);
l3ptr = l3ptr->next;
l1ptr = l1ptr->next;//更新兩個輸入鏈表
l2ptr = l2ptr->next;
}
//restPtr代表不空的那個(最多有一個),如果restPtr也空,則n不會進入下個if。
ListNode* restPtr = ( (l1ptr != NULL) ? l1ptr : l2ptr );
if (restPtr != NULL) {//數字1鏈表還沒用完
while (restPtr != NULL) {
curAdd = restPtr->val;
if (CarryFlag == 1) curAdd++;//若有進位則+1;
if (CarryFlag = curAdd / 10) curAdd -= 10;//判斷一下是否還有進位,如果有隻留一位數。
l3ptr->val = curAdd;
l3ptr->next = new ListNode(-1);
l3ptr = l3ptr->next;
restPtr = restPtr->next;
}
}
//到這裏時,數字鏈表一定都用完,記得這三種情況都要判斷是否最後時刻還有進位,以及前面多申請的val=-1的節點。
ListNode*pre = addNum,*p=pre->next;
while (p->next != NULL) {
pre = p;
p = p->next;
}
if (CarryFlag != 0) p->val = 1;
else{
pre->next = NULL;
delete p;
}
return addNum;
}
};
```
”