1、題目
給出兩個 非空 的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式存儲的,並且它們的每個節點只能存儲 一位 數字。
如果,我們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。
您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。
示例:
輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
原因:342 + 465 = 807
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/add-two-numbers
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
2、分析
從題目可以看出,兩個鏈表按位相加,存放在新的鏈表中,最後倒序輸出,即可以得到需要的值,,需要特別注意進位的實現。
3、實現
代碼
// 鏈表結構
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
// 兩數相加
ListNode* AddTwoNums(ListNode* l1, ListNode* l2)
{
ListNode* list = NULL;
ListNode* temp = NULL;
// 兩數相加,如果大於10,保存進位值。
int intNum = 0;
if (l1 == NULL && l2 == NULL)
{
return list;
}
list = new ListNode(0);
temp = list;
while (l1 != NULL || l2 != NULL)
{
int intA = (l1 != NULL) ? l1->val : 0;
int intB = (l2 != NULL) ? l2->val : 0;
int sum = intA + intB + intNum;
// 如果當前結果大於10 ,求出進位。
intNum = sum / 10;
// 取餘求出當前位的值,保存在新節點
temp->next = new ListNode(sum % 10);
temp = temp->next;
if (l1 != NULL)
{
l1 = l1->next;
}
if (l2 != NULL)
{
l2 = l2->next;
}
}
if (intNum > 0)
{
// 最後進位,添加新節點
temp->next = new ListNode(intNum);
}
return list->next;
}
測試用例
int main()
{
ListNode* l1 = new ListNode(4);
ListNode* curr = l1;
curr->next = new ListNode(0);
curr = curr->next;
curr->next = new ListNode(4);
ListNode* l2 = new ListNode(4);
curr = l2;
curr->next = new ListNode(5);
curr = curr->next;
curr->next = new ListNode(6);
// 計算4→0→4 + 4→5→6 ,結果爲 8→5→0→1 則爲正確。
// 即 404+654=1058
ListNode* re = AddTwoNums(l1, l2);
while (re!=NULL)
{
cout << re->val;
re = re->next;
}
cout << endl;
system("pause");
return 0;
}
測試結果
4、擴展
問題
有朋友問我,如果對原來的題目進行擴展,要求在原來的基礎上,返回值以正序方式存儲。應該怎麼實現呢?
示例:
輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
原因:243 + 564 = 807
分析
在逆序輸出時,我們返回鏈表的next域,即list->next,這樣方便進位。同樣,如果我們直接返回鏈表的本體list,則可以利用本體的val字段,將進位放在當前域即可。至於如何實現,小夥伴們可以先試試,後續我會將代碼實現和測試用例等一併同步。正文中實現的算法,相信各位小夥伴們都能實現,如果有更好更優的想法,可以留言或者私信我,不勝感激。如果你也在學習算法,請關注我,一起學習,共同進步!