2. 兩數相加

一、題目原型:

給定兩個非空鏈表來表示兩個非負整數。位數按照逆序方式存儲,它們的每個節點只存儲單個數字。將兩數相加返回一個新的鏈表。
你可以假設除了數字 0 之外,這兩個數字都不會以零開頭。

二、題目意思剖析:

將數字反過來,再相加,然后再逆序存起來。

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

三、解題思路:

官方解析:

1.將當前節點初始化為返回列表的啞節點。
2.將進位 carry 初始化為 0。
3.將 p 和 q 分別初始化為列表 l1 和 l2 的頭部。
4.遍歷列表 l1和 l2 直至到達它們的尾端。
5.將 x 設為節點 p 的值。如果 p 已經到達 l1的末尾,則將其值設置為0。
6.將 y 設為節點 q 的值。如果 q 已經到達 l2 的末尾,則將其值設置為0。
7.設定 sum=x+y+carry。更新進位的值,carry=sum/10。
8.創建一個數值為 (sum余10) 的新節點,并將其設置為當前節點的下一個節點,然后將當前節點前進到下一個節點。
9.同時,將 p 和 q 前進到下一個節點。檢查 carry=1 是否成立,如果成立,則向返回列表追加一個含有數字 1 的新節點。返回啞節點的下一個節點。

我的理解:

其實由繁化簡來說,就是保存sum的余數和sum的除數,也就是看看它是否超過了10,這有一個特殊處理。
比如 5 + 8 = 13,13 / 10 = 1,13 % 10 = 3。那其實就變成了3 -> 1
curr是先加余數,再加進位的那個1。

思路
// 1.鏈表構造
public class ListNode {
    public var val: Int
    public var next: ListNode?
    public init(_ val: Int) {
        self.val = val
        self.next = nil
    }
}
func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
    
    let dummyHead: ListNode? = ListNode.init(0)
    var p: ListNode? = l1
    var q: ListNode? = l2
    var curr: ListNode? = dummyHead
    
    var carray: Int = 0
    while (p != nil) || (q != nil) {
        let x: Int = (p != nil) ? (p?.val)! : 0
        let y: Int = (q != nil) ? (q?.val)! : 0
        let sum: Int = carray + x + y
        carray = sum / 10
        curr?.next = ListNode.init(sum % 10)
        curr = curr?.next
        if (p != nil) {
            p = p?.next
        }
        if (q != nil) {
            q = q?.next
        }
    }
    if carray > 0 {
        curr?.next = ListNode.init(carray)
    }
    return dummyHead?.next
}

四、小結

有時候抓住關鍵點就可以一擊突破。這題的關鍵就在于處理sum的余數和除數。

總提交數.png

提交結果.png

有任何疑問都可以留言,非常樂意一起探討。??

個人博客地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容