拿什麼拯救你,我的面試之——從零打卡刷Leetcode(No.002)

小詹學Python發表於2019-03-04

寫在前邊:

小詹一直覺得自己程式設計能力不強,想在網上刷題,又怕不能堅持。不知道有木有和小夥伴和小詹一樣想找個人一起刷題呢?歡迎和小詹一起定期刷leetcode,每週一週五更新一題,每一題都吃透,歡迎一題多解,尋找最優解!歡迎小夥伴們把自己的思路在留言區分享出來噢~

前期回顧:(附上使用頻繁的排序演算法python版)第一期的題目,有小夥伴分享了新的更優方法,可以看往期的置頂留言。

【記錄帖】(No.001)從零打卡刷Leetcode

程式設計師面試必備之排序演算法彙總(上)

程式設計師面試必備之排序演算法彙總(下)


No.2 Add Two Numbers

原題:

You are given two non-empty linked lists representing two non-negative integers. 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.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.

題目大意:給出兩個連結串列,儲存非負數,兩個連結串列都是按倒序方式儲存數字(個位,十位,百位……)要求將兩個連結串列相加並以連結串列形式返回。

例如:

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.複製程式碼

那麼在分析之前,先回顧下連結串列的基礎知識概念吧(大佬跳過,主要是小詹自己資料結構基礎不行)

① 什麼是連結串列?

舉個例子:在我們儲存一大波資料時,我們很多時候是使用陣列,但是當我們執行插入操作的時候就非常麻煩,有一堆資料1,2,3,5,6,7我們要在3和5之間插入4,如果用陣列,我們會怎麼做?當然是將5之後的資料往後退一位,然後再插入4,這樣非常麻煩,效率也非常低,但是如果用連結串列,我就直接在3和5之間插入4就行。

連結串列由一個個節點連線而成,節點結構如下:

拿什麼拯救你,我的面試之——從零打卡刷Leetcode(No.002)

其中data部分(資料域)儲存資料,next部分(指標域)儲存指標,指向下一個節點。任一個連結串列開始於頭指標head,頭結點的資料域可以不儲存資料。

② 連結串列基本操作?

初始化連結串列、連結串列長度、插入、刪除、新增、查詢、逆序。具體就不展開了~

回到本題上來~有多少人第一反應是這樣子的?舉起你的hand:

def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        len_max = max(len(l1),len(l2))
        carry = 0 #表示進位,例如9+8 = 17,carry = 1,預設進位為0
        for i in range(len_max):
            l3[i] = l1[i] + l2[i] + carry
            if l1[i] + l2[i] > 10:
                carry = 1
            else:
                carry = 0
        return l3
複製程式碼

以上應該挺好懂的吧,就不去具體講了(反正這個程式碼是不對的)

錯在哪呢?愛思考的小夥伴應該注意到了,其實思路沒有大的問題,畢竟加法我們還是學過的~主要有以下幾個小問題:

連結串列不同於列表陣列之類的,不能用len()獲取長度

★ 加法計算思考不全面,我們考慮到了存在的進位情況,但是沒考慮到連結串列長度不等,即兩個加數位數不等(比如三位數加五位數)

經過對錯誤程式碼的反思,我們考慮將題目拆分為兩個情況,以三位數加五位數為例,前三位數和前三位數按照我們已有的思路進行處理,第四位第五位則是另一種情況;具體就是:前三位數範圍內,對應位進行相加操作時附加上低位的進位;第四位第五位只用將該位加上低位的進位即可(或者理解成另一個三位數的高位為0)具體程式碼實現如下:

 def _addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        #指定到連結串列頭節點
        p = dummy = ListNode(-1)
        #進位標誌,低位有進位時為1,預設為0
        carry = 0
        #當兩個連結串列的同一位置同時不為空時(即小詹舉例的低三位數)
        while l1 and l2:
            #p.next為指標所指 l1.val為對應的資料
            p.next = ListNode(l1.val + l2.val + carry)
            #除法和求模運算獲取p.next的十位個位
            carry = p.next.val / 10
            p.next.val %= 10
            p = p.next
            l1 = l1.next
            l2 = l2.next
        res = l1 or l2 #或運算即對應小詹舉得高位例子(第四位第五位)
        while res:
            p.next = ListNode(res.val + carry)
            carry = p.next.val / 10
            p.next.val %= 10
            p = p.next
            res = res.next
        if carry:
            p.next = ListNode(1)
        return dummy.next#返回該連結串列
複製程式碼

是不是覺得完事了?敲完程式碼心裡那個舒坦,然而……執行發現有點小錯誤,這裡小詹先不揭祕,下期小詹再告訴大家上述程式在哪一個位置需要調整下才可以噢,找到的小夥伴留言區留下你的看法,第一個答對的有紅包噢!而排除了錯誤的執行效果還比較可觀:

拿什麼拯救你,我的面試之——從零打卡刷Leetcode(No.002)

如果覺得文章不錯,歡迎各種姿勢的轉發噢,讓更多人蔘與到我們的打卡隊伍中來噢!應小夥伴們要求,附建群二維碼,謝絕各種推廣【小詹自己也不會發除了leetcode打卡之外的公眾號文章】,純打卡討論群,謝謝各位大佬配合!已經超過一百人,可從公眾號新增小編微信邀請進群噢!


喜歡的小夥伴歡迎掃碼關注【小詹學Python】噢!

拿什麼拯救你,我的面試之——從零打卡刷Leetcode(No.002)


相關文章