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的余数和除数。

2. 两数相加_第1张图片
总提交数.png

2. 两数相加_第2张图片
提交结果.png

有任何疑问都可以留言,非常乐意一起探讨。

个人博客地址

你可能感兴趣的:(2. 两数相加)