一、題目原型:
給定兩個非空鏈表來表示兩個非負整數。位數按照逆序方式存儲,它們的每個節點只存儲單個數字。將兩數相加返回一個新的鏈表。
你可以假設除了數字 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
有任何疑問都可以留言,非常樂意一起探討。??