swift算法:两数相加

题目描述:

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 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
        
    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值