算法設計與分析 第一週

算法設計與分析 第一週

兩數相加


題目描述

這裏寫圖片描述


選題原因

第一次使用領釦,按照他的題目排列順序,選擇了一道中等難度的題目。由於算法課程還沒有很深入,因此沒有選擇課程相關題目。


題目分析

這道題的難點主要在於使用了鏈表表示數字,這樣做導致三個地方的處理需要十分謹慎:

  • 鏈表的鏈接
  • 兩數字數位不相等時,較長的數字需要再次加上去
  • 兩位數所有位數加完後,是否會產生進位

而由於最高位在鏈表尾端,反而使得運算變得簡單,不需要對齊操作。


解題思路

  • 由一首一尾兩個指針指向產生的新數字,每次得出新的一位,就更新尾端,最後返回首指針
  • 計算每一位時,得到結果後取十位作爲進位,個位作爲結果位
  • 先計算兩個數字的共同位數,計算完成後,再計算較長的數字的剩餘位,計算完成後,計算進位

問題

計算共同位數部分


  • 野指針問題

在創建新的數字鏈表過程中,使用了一個指針不停的new並指向next,並且用頭節點(頭節點爲空時)與尾節點(頭節點不爲空時)指向它。

        struct ListNode* l3;
        int add = 0;
        struct ListNode* t1 = l1;
        struct ListNode* t2 = l2;
        struct ListNode* tail;
        struct ListNode* t3;
        while (t1 -> next != NULL && t2 -> next != NULL) {
            int temp = t1 -> val + t2 -> val + add;
            t3 = new struct ListNode(temp % 10);
            if (l3 == NULL) {
                l3 = t3;
                tail = t3;
            } else {
                tail -> next = t3;
                tail = tail -> next;
            }
            add = temp / 10;
            t1 = t1 -> next;
            t2 = t2 -> next;
            t3 = t3 -> next;
        }

但是在編譯的過程中,卻出現了這樣的錯誤:
reference binding to misaligned address 0x5f5f7472617473 for type 'const int', which requires 4 byte alignment
出現綁定錯誤的問題,當 l3 = t3 賦值的時候,無法綁定地址,在查閱資料後,對所有的指針進行了初始化操作,再次編譯,結果正常。

        struct ListNode* l3 = NULL;
        int add = 0;
        struct ListNode* t1 = l1;
        struct ListNode* t2 = l2;
        struct ListNode* tail = NULL;
        struct ListNode* t3 = NULL;


  • 共同最高位無法計算

在循環中,判斷的條件爲 t1 -> next != NULL && t2 -> next != NULL ,但是在實際的操作中,共同的最高位時無法計算的,例如: [1,2,3] + [1,2,3],在計算到 3 時,就已經不在判斷條件範圍之內了,爲了解決這個問題,我在循環結束後,單獨進行了一次相同的運算,確保共同最高位能夠被計算。

        //計算共同最高位
        {
            int temp = t1 -> val + t2 -> val + add;
            t3 = new struct ListNode(temp % 10);
            if (l3 == NULL) {
                l3 = t3;
                tail = t3;
            } else {
                tail -> next = t3;
                tail = tail -> next;
            }
            add = temp / 10;
            t1 = t1 -> next;
            t2 = t2 -> next;
            t3 = t3 -> next;
        }

不等長數字高位部分


  • 判斷是否等長

我使用了新的指針指向了較長的那一個數字剩餘部分的最低位,並且以此爲判斷條件,繼續運算:

        //計算剩餘位
        {
            struct ListNode* t = NULL;
            if (t1 != NULL) {
                t = t1;
            } 
            if (t2 != NULL){
                t = t2;
            } 
            while (t -> next != NULL) {
                int temp = t -> val + add;
                t3 = new struct ListNode(temp % 10);
                if (l3 == NULL) {
                    l3 = t3;
                    tail = t3;
                } else {
                    tail -> next = t3;
                    tail = tail -> next;
                }
                add = temp / 10;
                t = t -> next;
                t3 = t3 -> next;
            }

在操作中,發現如下報錯: Line 59: member access within null pointer of type 'struct ListNode'
當兩個數字等長時,則得到的新指針是空的,因此是無法指向下一個next 的,因此,在循環開始之前加上判斷的部分: if (t != NULL)

進位部分

進位部分較爲簡單,沒有什麼問題。


源代碼

/**
 * 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) {
        struct ListNode* l3 = NULL;
        int add = 0;
        struct ListNode* t1 = l1;
        struct ListNode* t2 = l2;
        struct ListNode* tail = NULL;
        struct ListNode* t3 = NULL;
        while (t1 -> next != NULL && t2 -> next != NULL) {
            int temp = t1 -> val + t2 -> val + add;
            t3 = new struct ListNode(temp % 10);
            if (l3 == NULL) {
                l3 = t3;
                tail = t3;
            } else {
                tail -> next = t3;
                tail = tail -> next;
            }
            add = temp / 10;
            t1 = t1 -> next;
            t2 = t2 -> next;
            t3 = t3 -> next;
        }
        //計算共同最高位
        {
            int temp = t1 -> val + t2 -> val + add;
            t3 = new struct ListNode(temp % 10);
            if (l3 == NULL) {
                l3 = t3;
                tail = t3;
            } else {
                tail -> next = t3;
                tail = tail -> next;
            }
            add = temp / 10;
            t1 = t1 -> next;
            t2 = t2 -> next;
            t3 = t3 -> next;
        }
        //計算剩餘位
        {
            struct ListNode* t = NULL;
            if (t1 != NULL) {
                t = t1;
            } 
            if (t2 != NULL){
                t = t2;
            } 
            if (t != NULL) {
                while (t -> next != NULL) {
                    int temp = t -> val + add;
                    t3 = new struct ListNode(temp % 10);
                    if (l3 == NULL) {
                        l3 = t3;
                        tail = t3;
                    } else {
                        tail -> next = t3;
                        tail = tail -> next;
                    }
                    add = temp / 10;
                    t = t -> next;
                    t3 = t3 -> next;
                }
                {
                    int temp = t -> val + add;
                    t3 = new struct ListNode(temp % 10);
                    if (l3 == NULL) {
                        l3 = t3;
                        tail = t3;
                    } else {
                        tail -> next = t3;
                        tail = tail -> next;
                    }
                    add = temp / 10;
                    t = t -> next;
                    t3 = t3 -> next;
                }
            }
        }
        //計算最高位進位
        {
            if (add != 0) {
                t3 = new struct ListNode(add);
                if (l3 == NULL) {
                    l3 = t3;
                    tail = t3;
                } else {
                    tail -> next = t3;
                    tail = tail -> next;
                }
            }
        }
        return l3;
    }
};

運行結果

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章