一、题目原型:
给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。
你可以假设除了数字 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的余数和除数。
有任何疑问都可以留言,非常乐意一起探讨。😄