LeetCode 題庫練習 2

題目:
給出兩個 非空 的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式存儲的,而且它們的每一個節點只能存儲 一位 數字。node

若是,咱們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。git

您能夠假設除了數字 0 以外,這兩個數都不會以 0 開頭。github

示例:數組

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

分析題目

題目中給出了鏈表的定義,鏈表有兩個成員,一個 val 表示當前節點所存儲的值,next 表示指向的下一個節點,顯然,當 next 爲 None 時,說明鏈表結束:優化

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

解法1:爲了獲得兩個數的和,能夠先將兩個鏈表表示的數字計算出來,獲得和後再以鏈表的形式返回。
解法2:每一個鏈表的節點都是從低位到高位的,直接將對應節點位置的兩數相加,存放到和的鏈表中,若出現進位,則置進位標誌位爲 1,當其中一個鏈表沒有更多的節點時,用 0 表示,最後以鏈表的形式返回和。指針

解題

我採用的是第 2 種方法:code

nodestart = ListNode(0)
result = nodestart

l1start = ListNode(0)
l1start.next = l1
l2start = ListNode(0)
l2start.next = l2

nextLevelup = False  #  carry flag

首先構造了 nodestart = ListNode(0) 準備存放第一個數,將結果 result 指向該節點,而後分別構造 l1startl2start,分別指向傳入的兩個鏈表(這裏的構造形式和後面的循環有關)。接着對每一位進行相加:blog

num1 = l1start.val if l1start is not None else 0
num2 = l2start.val if l2start is not None else 0
if nextLevelup:
    num1 += 1
    nextLevelup = False

num1 += num2
if num1 > 9:
    nextLevelup = True
    num1 -= 10
result.next = ListNode(num1)
result = result.next

取出加數和被加數相應節點的數,分別設爲 num1 和 num2,若上一次相加時,有進位發生,加將 num1 加 1,並加 num1 和 num2 相加,和存儲在 num1 中,若 num1 > 9,說明發生了進位,須要進行進位的處理。最後用 num1 構造一個新的節點,移動 result 指針指向該節點。內存

這裏的代碼是在循環中執行的,當兩個鏈表指針 l1start 和 l2start 的 next 都爲 None 時,循環結束。

解題完整代碼:github 僅供參考。

上面的解題過程能夠進一步優化,咱們已經用 num1 來存儲最後的和了,能夠再將 l1start 節點中的值修改爲最後獲得的 num1,這樣能夠避免建立過多的新節點,減小內存使用。

解題小結

鏈表 ListNode 中的每個節點實際上表示的是數字的每一位,根據加法的運算規則,對兩個鏈表的每一位相加便可獲得最終的和。

想象:對於每一位的加法來講,實際上能夠同時計算幾個位數的加法,好比同時進行 4 對節點的相加,例如:1535 + 1329,若並行計算 4 位的加法,獲得每一位上的和分別爲 2 8 5 4,但最後一位出現進位,致使結果更新爲 2864,或者 1545 + 1491,並行計算,得每一位上的和爲 2 9 3 6,第 3 位出現進位,致使第 2 位進位,最終致使第 1 位進位,結果更新爲 3036。用這樣的原理是否是就能夠實現硬件級別的加速呢?

類似題目

在 LeetCode 題庫中的第 9 題,判斷一個數字是不是迴文數。在不將整數轉爲字符串的前提下,能夠用上面的思想來進行解題。

方法:構造一個數組,數組從 0 開始,存儲數字的低位到高位:

xlist = []
while x > 0:
    x, tmp = divmod(x, 10)
    xlist.append(tmp)

如 13432,在數組中就是 [1, 3, 4, 3, 2],而後判斷第 i 位,與第 xlistLen - 1 - i 位是否相等,若對於全部的 i 都相等,則該數字是迴文數,不然就不是迴文數。

xlen = len(xlist)
for i in range(xlen // 2):
    if xlist[i] != xlist[xlen - 1 - i]:
        return False
return True

事實上,構造數組的那部分代碼就和將整數轉換爲字符串是同樣的效果,不過這裏是用求餘的方法獲得各個位數上的數的。

該部分的完整代碼地址:github 僅供參考。

相關文章
相關標籤/搜索