Skip to content

算法:两数相加

轩辕十四
Published date:

Table of contents

Open Table of contents

题目

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例 1:

img

输入: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]

提示:

解法

func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
  if l1 == nil || l2 == nil {
    return l1 ?? l2
  }

  var cur1 = l1
  var cur2 = l2
  let sum = cur1!.val + cur2!.val
  var carry = sum / 10
  let head = ListNode(sum % 10)
  var cur: ListNode? = head

  while cur1?.next != nil || cur2?.next != nil {
    let value1 = cur1?.next?.val ?? 0
    let value2 = cur2?.next?.val ?? 0
    let sum = value1 + value2  + carry
    carry = sum / 10
    cur?.next = ListNode(sum % 10)
    cur = cur?.next
    cur1 = cur1?.next
    cur2 = cur2?.next
  }

  if carry > 0 {
    cur?.next = ListNode(carry)
  }

  return head
}

解题思路

两数相加问题的主要思路是,将两个数字表示成逆序链表,每个节点存储一个数字位。步骤如下:

  1. 从头节点开始相加:由于链表是逆序存储,链表的头节点就是数字的个位,从最低位开始相加。

  2. 计算和与进位:将对应的两个节点的值相加,同时加上上一次运算的进位,得到当前的和。

  1. 构造结果链表:每计算出一位的值,就构造一个新的节点,将其接入结果链表中。

  2. 遍历所有节点:同时遍历两个链表,直到两个链表的所有节点都被处理完毕。如果还有进位,则需要在链表末尾插入一个新节点来表示该进位。

  3. 考虑特殊情况:如果输入链表为空或只存在其中一个链表的情况,也要正确处理。

代码实现详细讲解

下面详细解释代码中每一部分的功能和实现细节:

if l1 == nil || l2 == nil {
  return l1 ?? l2
}

输入判断:

如果任意一个链表为空,直接返回非空的那个链表。

其中,⁠l1 ?? l2 表示如果 ⁠l1 非空则返回 ⁠l1,否则返回 ⁠l2


var cur1 = l1
var cur2 = l2
let sum = cur1!.val + cur2!.val
var carry = sum / 10
let head = ListNode(sum % 10)
var cur: ListNode? = head

变量初始化:


while cur1?.next != nil || cur2?.next != nil {
  let value1 = cur1?.next?.val ?? 0
  let value2 = cur2?.next?.val ?? 0
  let sum = value1 + value2  + carry
  carry = sum / 10
  cur?.next = ListNode(sum % 10)
  cur = cur?.next
  cur1 = cur1?.next
  cur2 = cur2?.next
}

遍历剩余节点:

使用 ⁠while 循环处理两个链表中剩余的节点,条件是任意一个链表还有后续节点。


if carry > 0 {
  cur?.next = ListNode(carry)
}

处理最后的进位:

循环结束后,可能最后一次运算后仍有进位(例如相加得到的和大于等于 10)。

如果 ⁠carry 大于 0,则新建一个节点保存进位,并将其接入链表末尾。

Previous
算法:无重复字符的最长子串
Next
数据结构与算法:数组的基本原理