LeetCode Python3——2. 兩數相加

問題描述

給出兩個非空的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照逆序的方式存儲的,並且它們的每個節點只能存儲 一位數字。如果,我們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。

示例:

輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
原因:342 + 465 = 807

測試用例 說明
l1=[0,1]l1=[0,1] l2=[0,1,2]l2=[0,1,2] 當一個列表比另一個列表長時。
l1=[]l1=[] l2=[0,1]l2=[0,1] 當一個列表爲空時,即出現空列表。
l1=[9,9]l1=[9,9] l2=[1]l2=[1] 求和運算最後可能出現額外的進位,這一點很容易被遺忘

Sol 1:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """  
        re = ListNode(0)
        r=re
        carry=0
        while(l1 or l2):
            x= l1.val if l1 else 0 #往後面補0
            y= l2.val if l2 else 0
            s=carry+x+y   #進位,超過十進一
            carry=s//10  #取整的正確用法
            r.next=ListNode(s%10) #取餘
            r=r.next
            if(l1!=None):l1=l1.next
            if(l2!=None):l2=l2.next
        if(carry>0): #如果最後一位相加超過10,再進一位給一 4000+6000=10000
            r.next=ListNode(1)
        return re.next

這裏要提醒各位:如果自己寫的過程中超時了,說明你的代碼有問題,可能運行時間超過的規定。(也許你在本地環境下是可以運行的,但在這裏不夠好)

代碼解析:

  1. 注意這裏的鏈表概念,代碼中首先初始化了一個鏈表re,然後又複製了這個鏈表r(這兩個鏈表的指向相同),由於在鏈表移動的過程中要不停的變換當前的地址,指向下一個地址,所以r鏈表充當這個角色,不停的指向下一個地址。但是,re指向的是r經過的所有地址,如圖所示,r最後的val爲8,而re.next指向的是7,0,8。
    在這裏插入圖片描述
  2. 其次,這裏還用的carrycarry,用進位來代替位數相加由於每位數字都應當處於 090 \ldots 9的範圍內,我們計算兩個數字的和時可能會出現“溢出”。例如,5+7=125 + 7 = 12。在這種情況下,我們會將當前位的數值設置爲 22,並將進位 carry=1carry = 1帶入下一次迭代。進位 carry必定是 0011,這是因爲兩個數字相加(考慮到進位)可能出現的最大和爲 9+9+1=199 + 9 + 1 = 19

時間複雜度:O(max(m,n))O(\max(m, n)),假設 mmnn 分別表示l1l1l2l2 的長度,上面的算法最多重複 max(m,n)max(m,n)次。
空間複雜度:O(max(m,n))O(\max(m, n)),新列表的長度最多爲 max(m,n)+1max(m,n)+1。運行時間爲116ms,內存佔用爲6.7M。

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