1. 程式人生 > >Add Two Numbers(基於連結串列的兩數相加)

Add Two Numbers(基於連結串列的兩數相加)

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

1.個人分析
由題意和示例可以看出,連結串列從第一個節點開始,依次表示非負數的個位、百位、千位等等。對連結串列每個節點進行相加操作也遵循正常的進位。最直接的做法是同時遍歷兩個連結串列,將每個節點進行相加,如果有進位,則對求和結果取餘,並在下一節點求和時加1。

2.個人解法

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2)
{
    ListNode *res = new ListNode(0);//建立一個空節點作為結果連結串列的頭節點
    ListNode *resCur = res;
    ListNode *cur1 = l1;
    ListNode *
cur2 = l2; int carry = 0; //進位值 //處理兩連結串列相同長度的情況 while (cur1 && cur2){ int tmp = cur1->val + cur2->val + carry; carry = tmp >= 10 ?1 : 0; int unit = tmp % 10; ListNode *newNode = new ListNode(unit); resCur->next = newNode; resCur =
newNode; cur1 = cur1->next; cur2 = cur2->next; } if(cur1){ //處理l1長度比l2長度更長的情況 while(cur1){ int tmp = cur1->val + carry; carry = tmp >= 10 ?1 : 0; cur1->val = tmp % 10; resCur->next = cur1; resCur = cur1; cur1 = cur1->next; } } else if(cur2){ //處理l2長度比l1長度更長的情況 while(cur2){ int tmp = cur2->val + carry; carry = tmp >= 10 ?1 : 0; cur2->val = tmp % 10; resCur->next = cur2; resCur = cur2; cur2 = cur2->next; } } //處理最高位進位情形 if(carry == 1){ ListNode *newNode = new ListNode(carry); resCur->next = newNode; resCur = newNode; } return res->next; }

該解法的時間複雜度為O(n),空間複雜度為O(n),但整體流程顯得比較冗長。

3.參考解法

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2)
{
    ListNode preHead(0), *p = &preHead;
    int extra = 0;
    while (l1 || l2 || extra) {
        if (l1) extra += l1->val, l1 = l1->next;
        if (l2) extra += l2->val, l2 = l2->next;
        p->next = new ListNode(extra % 10);
        extra /= 10;
        p = p->next;
    }
    return preHead.next;
}

該解法的時間複雜度為O(n),空間複雜度為O(n),執行效率與第一種解法差不多,但整體程式碼更加精簡。

4.總結
該問題雖然不難想出解法,但需要考慮很多的細節,比如不等長的情形處理,最高位進位的處理,所以想要一次就AC不太容易。

PS:

  • 題目的中文翻譯是本人所作,如有偏差敬請指正。
  • 其中的“個人分析”和“個人解法”均是本人最初的想法和做法,不一定是對的,只是作為一個對照和記錄。