leetcode 2 两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
解题思路:
根据加法的准则,从链表头开始相加,通过整除可以知道是否有进位,通过取余获取余数并记录下来。如果有进位就记录进位,进行下一位相加时把进位数一起加上,然后重复上面操作,最后返回记录余数的result。遇到两个数字长度不一,可以补零继续操作。
递归法需要判断如果链表后面没值了,就补上零。结束条件是两个链表为空或进位为0
代码思路:
暴力法:
创建一个空链表存储结果,然后使用cur作为指针指向res,因为我们需要移动去存储链表结果,remain是记录进位数的。循环的结束条件是两个链表都为空,判断链表是否为空可以解决长度不一的问题,如果为None就可以跳过了。计算完total,就可以重新计算余数和进位数,并且移动cur指针。直到把所有元素都遍历一次,判断是否还有进位数,有的话就还有创建一个节点去记录下来添加到result中,返回结果为res.next,因为res的头结点是空结点
递归法:
直接就开始运算,然后digit记录进位数,remain记录余数,res保存结果。结束条件是两个链表都为空而且也没有进位数。 循环操作两个链表,可以判断是否有.next来解决长度不一,直接在链表L1的值上加上进位数,然后跳到下一个递归层中,赋值给res.next,就会形成一个链表的格式
代码:
(暴力法)
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
res = ListNode()
cur = res
remain = 0
while l1 != None or l2 != None:
total = remain
if l1 != None:
total += l1.val
l1 = l1.next
if l2 != None:
total += l2.val
l2=l2.next
remain = total // 10
cur.next = ListNode(total%10)
cur = cur.next
if remain != 0:
cur.next = ListNode(remain)
cur = cur.next
return res.next
(递归法)
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
total = l1.val + l2.val
digit = total // 10
remain = total % 10
res = ListNode(remain)
if l1.next or l2.next or digit:
l1 = l1.next if l1.next else ListNode(0)
l2 = l2.next if l2.next else ListNode(0)
l1.val += digit
res.next = self.addTwoNumbers(l1,l2)
return res
复 杂 度 分 析 : \color{red}{复杂度分析:} 复杂度分析:
两个方法的时间复杂度为O(max(M,N)),最大复杂度是最长链表的长度,每个操作都为O(1)