题目描述:
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入 (2->4->3)+(5->6->4)
输出 (7->0->8)
原因 342+465 = 807
思路
我们使用变量来跟踪进位,并从包含最低有效位的表头开始模拟逐位相加的过程。
图1,对两数相加方法的可视化: 342+465=807342+465=807,每个结点都包含一个数字,并且数字按位逆序存储。
解法一:
伪代码:
- 将当前结点初始化为返回列表的哑结点。
- 将进位 carrycarry 初始化为 00。
- 将 pp 和 qq 分别初始化为列表 l1l1 和 l2l2 的头部。
- 遍历列表 l1l1 和 l2l2 直至到达它们的尾端。
- 将 xx 设为结点 pp 的值。如果 pp 已经到达 l1l1 的末尾,则将其值设置为 00。
- 将 yy 设为结点 qq 的值。如果 qq 已经到达 l2l2 的末尾,则将其值设置为 00。
- 设定 sum=x+y+carrysum=x+y+carry。
- 更新进位的值,carry=sum/10carry=sum/10。
- 创建一个数值为 (sum mod 10)(summod10) 的新结点,并将其设置为当前结点的下一个结点,然后将当前结点前进到下一个结点。
- 同时,将 pp 和 qq 前进到下一个结点。
- 检查 carry=1carry=1 是否成立,如果成立,则向返回列表追加一个含有数字 11 的新结点。
- 返回哑结点的下一个结点。
请注意,我们使用哑结点来简化代码。如果没有哑结点,则必须编写额外的条件语句来初始化表头的值。
请特别注意以下情况:
测试用例 | 说明 |
---|---|
l1=[0,1]l1=[0,1],l2=[0,1,2]l2=[0,1,2] | 当一个列表比另一个列表长时 |
l1=[]l1=[],l2=[0,1]l2=[0,1] | 当一个列表为空时,即出现空列表 |
l1=[9,9]l1=[9,9],l2=[1]l2=[1] | 求和运算最后可能出现额外的进位,这一点很容易被遗忘 |
/* Definition for singly-linked list.
public class ListNode {
public var val: Int
public var next: ListNode?
public init(_ val: Int) {
self.val = val
self.next = nil
}
}*/
class Solution {
func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
/* 解法2-非递归--20s
1、定义一个新节点l3,初始化为0,定义一个当前节点,赋值为l3,定义一个值表示进位(0/1)
2、定义p、q表示l1\l2
3、当其中一个不为空时,执行while循环
定义x = p不为空时,x为p.val,反之为0
定义y = q不为空时,y为q.val,反之为0
定义s = x+y+进位值carry
carry = 当s<10 为 0,反之为 1
current的下一个next = init(s%10)
current = current.next
当p不为空时,p=p的下一个节点
当q不为空时,q=q的下一个节点
当进位值大于0时,current的下一个节点=init(1)
*/
var l3 : ListNode? = ListNode.init(0)
var current : ListNode? = l3
var carry : Int = 0
var p = l1
var q = l2
while (p != nil) || (q != nil) {
let x = (p != nil) ? p!.val : 0
let y = (q != nil) ? q!.val : 0
let s = x+y+carry
carry = (s < 10) ? 0 : 1
current!.next = ListNode.init(s%10)
current = current!.next
if (p != nil) {
p = p!.next
}
if (q != nil) {
q = q!.next
}
}
if (carry > 0){
current!.next = ListNode.init(1)
}
return l3!.next
}
}
解法二:
/* Definition for singly-linked list.
public class ListNode {
public var val: Int
public var next: ListNode?
public init(_ val: Int) {
self.val = val
self.next = nil
}
}*/
class Solution {
func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
//递归版本
/*
1、如果两个都为空,则返回空
2、其中一个为空,直接返回其中不为空的那个
3、两个都不为空,创建一个新节点,并初始化为l1.val和l2.val值的和除10得余数
4、判断l1.val和l2.val值的和是否大于等于10
大于等于10,调用((l1.next,l2.next),init(1))
小于10,调用(l1.next,l2.next)
*/
/*解法1--16s*/
if (l1 == nil)&&(l2 == nil) {
return nil
}
if (l1 == nil) {
return l2
}
if (l2 == nil){
return l1
}
var l3 : ListNode? = ListNode.init((l1!.val+l2!.val)%10)
if (l1!.val+l2!.val)>=10 {
l3!.next = addTwoNumbers(addTwoNumbers(l1!.next,l2!.next),ListNode.init(1))
}else{
l3!.next = addTwoNumbers(l1!.next,l2!.next)
}
return l3
}
}