【題目】:
You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
【題意】:
首先題意理解,輸入為兩個單連結串列,每一個連結串列的元素均為0~9的數字,而每一個連結串列示一個數字,頭部是最低位,尾部是最高位。例如上述題目中Input的兩個連結串列分別表示342 以及 465.
那麼問題就來了,輸出為新的連結串列,該連結串列以同樣的方式表示輸入的兩個數字之和。
【Key Point】:
記錄進位
【坑】:
可以寫兩個方法,將連結串列內容轉換成數字,以及將數字轉換成對應的連結串列。於是就有了以下步驟:
- list1, list2 <convertListToNum> num1, num2;
- value = num1 + num2;
- value <convertNumToList> newList;
如果題目中規定了連結串列的長度,這種方法未嘗不可,可是沒有~ 計算機中無論int(最大表示到2^4),long(最大也表示到2^4),long long(最大表示到2^8)等都有極限,而連結串列理論上可以形成很大的數字,很容易就能夠突破 , 所以使用數值型別來儲存結果是不可能通過所有case的。因此可以使用非數值型來儲存,但是無形中增加了該題目的複雜度。
【解答】:
既然題目給的連結串列結果就是從低位向高位(很舒服,如果逆向又得費點事),逐次針對連結串列兩個元素進行相加,記錄每一次的進位,注意 題目並沒有說輸入的兩個連結串列長度一致。以下是程式碼實現,通過leetCode的OJ
1 class Solution { 2 public: 3 // 記錄每一次的進位,這樣就突破了數值型的限制 4 ListNode *addTwoNumbers2(ListNode *l1, ListNode *l2){ 5 ListNode *root = NULL, *pre = NULL; 6 int nCarry = 0; // 每一個數位能夠產生的進位最多為1,所以可以採用bool或者1bit表示 7 8 while (NULL != l1 || NULL != l2){ 9 int nodeVal = 0; 10 if (NULL == l1){ 11 nodeVal = l2->val + nCarry; 12 l2 = l2->next; 13 } 14 else if (NULL == l2){ 15 nodeVal = l1->val + nCarry; 16 l1 = l1->next; 17 } 18 else{ 19 nodeVal = l1->val + l2->val + nCarry; 20 l1 = l1->next; 21 l2 = l2->next; 22 } 23 24 if (nodeVal >= 10){ // 產生進位 25 nCarry = 1; 26 nodeVal %= 10; 27 } 28 else{ 29 nCarry = 0; // 進位清零 30 } 31 32 ListNode *node = new ListNode(nodeVal); 33 if (pre == NULL){ 34 root = node; 35 } 36 else{ 37 pre->next = node; 38 } 39 pre = node; // 記錄上次節點,串聯整個連結串列使用 40 }// while 41 42 if (nCarry != 0){ // 當連結串列結束如果還有進位,需要增加一個最高位節點 43 ListNode * lastNode = new ListNode(nCarry); 44 45 if (NULL != pre){ 46 pre->next = lastNode; 47 } 48 }// nCarry != 0 49 50 return root; 51 } 52 }
【leetCode Submission】
【執行結果】:
如果有什麼問題,希望各位不吝賜教,小弟感恩答謝!