(LeetCode刷題)Day 02 Add Two Numbers 兩數相加

Add Two Numbers

Add Two Numbers

題目描述(中等難度)

在這裏插入圖片描述
在這裏插入圖片描述
該題目的目標是:兩個鏈表表示的數相加,這樣就可以實現兩個很大的數相加了,就不用考慮數據類型方面的位數限制了。

方法:初等數學

我們使用變量來跟蹤進位,並從包含最低有效位的表頭開始模擬逐位相加的過程。

過程圖示

在這裏插入圖片描述
根據上圖可知,對兩數相加方法的可視化:342+465=807342+465=807,每個結點都包含一個數字,並且數字按位逆序存儲。

算法描述

如同我們需要在草稿紙上像小學時候那樣來用豎式來計算對應的結果一樣,我們首先可以從最低的有效位,也就是列表中的 l1l1l2l2 的表頭開始相加。由於每位數字都應當處於 0...90...9的範圍之內,因此我們需要計算兩個數字的和的時候可能會出想當前位“溢出”的情況。

例如, 9+8=179+8 = 17。在這種情況下,我們會將當前位的數值設置爲 77,並將進位 carry=1carry = 1,將其帶入到下一次的迭代中去。這裏的進位 carrycarry必定是0或者1,這是因爲兩個數字相加考慮到進位的時候,最大的數字也就是 9+9+1=199+9+1=19

因此,僞代碼描述如下:

在這裏插入圖片描述
C++代碼

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(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) {
        // pst中存儲表頭
        ListNode  *pst;
        pst = l1;
        // 直接將答案存儲在l1中,las處理進位
        l1 -> val += l2 -> val;
        int las = l1 -> val / 10;
        l1 -> val %= 10;
        // l1和l2均爲非空時的情況處理
        while(l1 -> next != NULL && l2 -> next != NULL)
        {
            l1 = l1 -> next;
            l2 = l2 -> next;
            l1 -> val += l2 -> val + las;
            las = l1 -> val / 10;
            l1 -> val %= 10;
        }
        // l1空而l2非空時的情況處理
        while(l2 -> next != NULL)
        {
            l2 = l2 -> next;
            l1 -> next = new ListNode(l2 -> val + las);
            l1 = l1 -> next;
            las = l1 -> val / 10;
            l1 -> val %= 10;
        }
        // 可以同時處理l1非空而l2空,以及最後las中需要進位的情況處理
        while(las > 0)
        {
            if(l1 -> next == NULL) l1 -> next = new ListNode(las);
            else l1 -> next -> val += las;
            l1 = l1 -> next;
            las = l1 -> val / 10;
            l1 -> val %= 10;
        }
        return pst;
    }
};

Golang代碼:

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
    carry:=0
    w:=0
    sum:=0
    head:=&ListNode{Val:0}
    prev:=head
    for l2 != nil&&l1 != nil  {
        sum = l1.Val+l2.Val+carry
        w=sum%10
        carry=sum/10
        prev.Next = &ListNode{Val:w}
        prev = prev.Next
        l1 = l1.Next
        l2 = l2.Next
        //fmt.Println(carry)
    }
    if l2==nil {
        l2 = l1
    }

    for l2!=nil||carry != 0 {
        x:=0
        if l2!=nil{
            x=l2.Val
            l2 = l2.Next
        }
        sum = x+carry
        w= sum%10
        carry = sum/10
        prev.Next = &ListNode{Val:w}
        prev = prev.Next
    }
    return head.Next
   
}

時間複雜度: O(max(m,n))O(max(m,n)),m 和 n 代表 l1l1l2l2 的長度。
空間複雜度:** O(max(m,n))O(max(m,n)),m 和 n 代表 l1l1l2l2 的長度,而其實新的ListList最大長度是O(max(m,n))+1O(max(m,n)) + 1,因爲我們沒有headhead這樣的存儲值。

在這裏插入圖片描述
成長,就是一個不動聲色的過程,一個人熬過一些苦,才能無所不能。 ​​​​

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