LeetCode之HOT100--002两数相加

686 阅读3分钟

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」。

前言

一直都计划学习数据结构与基本算法,但是平时都看一阵停一阵。现在决心坚持下去,我准备从LeetCode的HOT100开始,每天完成1~2道习题,希望通过这种方式养成持续学习的习惯。因为我是做iOS开发的,主要是用Objective-C语言,最近也在学习Swift,所以本系列的题解都将使用swift语言完成,本文更新的是LeetCode中HOT100的第2题002两数相加。

题目

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例 1:

输入: l1 = [2,4,3], l2 = [5,6,4]
输出: [7,0,8]
解释: 342 + 465 = 807.

示例 2:

输入:l1 = [0], l2 = [0]
输出:[0]

示例 3:

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

分析

本题的意义其实就是两个整数的加法计算的模拟过程,由于输入的两个链表都是逆序存储数字的位数的,因此两个链表中同一位置的数字可以直接相加。
我们同时遍历两个链表,逐位计算它们的和,并与当前位置的进位值相加。具体而言,如果当前两个链表处相应位置的数字为 n1,n2,进位值为 carry,则它们的和为 n1+n2+carry;其中,答案链表处相应位置的数字为(n1+n2+carry)mod10(此处的mod表示求余),而新的进位值为 (n1+n2+carry)/10 (此处的除/表示整除)。
如果两个链表的长度不同,则可以认为长度短的链表的后面有若干个 0 。
此外,如果链表遍历结束后,有 carry>0,还需要在答案链表的后面附加一个节点,节点的值为 carry。

题解

/** 
 * Definition for singly-linked list. 
 * public class ListNode { 
 *     public var val: Int 
 *     public var next: ListNode? 
 *     public init() { self.val = 0; self.next = nil; } 
 *     public init(_ val: Int) { self.val = val; self.next = nil; } 
 *     public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; } 
 * } 
 */ 
class Solution {
     func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
         //有一个链表为空时,不用计算,直接返回另一个链表即可
         if l1 == nil { return l2 } 
         if l2 == nil { return l1 } 
         var addVal = 0  //进位上的值carry
         var curl1 = l1  //链表1当前的值 n1
         var curl2 = l2  //链表2当前的值 n2
         var curResNode:ListNode? = nil //结果链表的当前节点
         var ansNode :ListNode? = nil  //结果链表的头结点
         while curl1 != nil || curl2 != nil || addVal != 0 {
             let tempAns = (curl1?.val ?? 0) + (curl2?.val ?? 0) + addVal 
             addVal = tempAns / 10  //计算进位上的值
             let node = ListNode(tempAns%10)  //创建当前结果节点
             if curResNode == nil { 
                 ansNode = node 
                 curResNode = node 
             } else { 
                 curResNode?.next = node 
                 curResNode = node 
             } 
             //下一位上继续
             curl1 = curl1?.next 
             curl2 = curl2?.next 
         } 
         curResNode?.next = nil 
         return ansNode 
     } 
}