002——两数相加

002——两数相加

1.题目

002——两数相加

2.我的解决方案

2.1第一次解决方案

  • 思路:
    • 从长度入手,计算链表长度,通过指针交换,固定l2为较长的那一个
    • 链表长度相等时,为了防止遍历到最后一个节点l2=l2.next=None,但是此时最高位向下一位产生进位,无法再添加结点情况,while循环到次高位节点,最高位的加法单独处理
    • l2链表长时,先计算公共部分的加法,结束之后,为了防止出现1+999这样的连续进位,循环验证l2,同上,为了防止最高位向下一位进位而指针l2=l2.next=None而无法添加结点的情况,将l2的最高位做单独的处理
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
def getLength(l):   # 计算单链表长度
    length = 0
    if not l:
        return 0
    else:
        while l:
            length += 1
            l = l.next
        return length
        
class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        length1 = getLength(l1)
        length2 = getLength(l2)
        flag = False
        if length1 > length2:   # 保持l2为长链表
            l3 = l1
            l1 = l2
            l2 = l3

        l3 = l2     # 直接在l2上相加,l3指向l2
        if length1 == length2:  # 当长度相同时
            while l1.next:  # 为了防止产生最高位进位,添加结点时指针丢失,用next
                if flag:
                    l2.val += 1
                    flag = False
                l2.val += l1.val
                if l2.val > 9:
                    l2.val -= 10
                    flag = True
                l1 = l1.next
                l2 = l2.next
            if flag:    # 如果向最高位进位
                l2.val += 1
                flag = False     
            l2.val += l1.val
            if l2.val > 9:
                l2.val -= 10
                flag = True
            if flag:    # 最高位向下一位进位(添加结点)
                l2.next = ListNode(1)
        else:   # l2长时
            while l1:   # 计算公共部分
                if flag:    
                    l2.val += 1
                flag = False
                l2.val += l1.val
                if l2.val > 9:
                    l2.val -= 10
                    flag = True
                l1 = l1.next
                l2 = l2.next
            while l2.next:  # 计算l2多余部分,同样,为了防止添加节点时指针丢失,用next
                if flag:
                    l2.val += 1
                flag = False
                if l2.val > 9:
                    l2.val -= 10
                    flag = True
                l2 = l2.next
            if flag:    # 向最高位进位
                l2.val += 1
                flag = False
                if l2.val > 9:
                    l2.val -= 10
                    flag = True
            if flag:    # 最高位向下一位进位
                l2.next = ListNode(1)
        return l3

2.2 我的改良

  • 将最高位拿出来单独判断造成代码有过多的冗余
  • 冗余是为了防止最高位向下一位产生进位时,指针成为None丢失而不能再添加结点的问题出现,采用l1.next和l2.next作为终止条件将最高位单独拿出来判断造成的
  • 为了解决上述问题,引入滚动的指针p,使其始终指向l2所指向结点的前一个结点,就能避免指针的丢失
  • 引入p之后,长度相等和不等两种情况下公共部分代码的相加可以合并
  • 公共部分加法完成之后,判断l2是否有剩余
  • 最后判断最高位是否产生进位
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
def getLength(l):   # 计算单链表长度
    length = 0
    if not l:
        return 0
    else:
        while l:
            length += 1
            l = l.next
        return length
        
class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        length1 = getLength(l1)
        length2 = getLength(l2)
        flag = False
        if length1 > length2:   # 保持l2为长链表
            l3 = l1
            l1 = l2
            l2 = l3

        l3 = l2     # 直接在l2上相加,l3指向l2
        while l1:  # 公共部分相加
            if flag:
                l2.val += 1
                flag = False
            l2.val += l1.val
            if l2.val > 9:
                l2.val -= 10
                flag = True
            l1 = l1.next
            p = l2
            l2 = l2.next
        while l2:   # 当l2有剩余时
            if flag:
                l2.val += 1
                flag = False
            if l2.val > 9:
                l2.val -= 10
                flag = True
            p = l2
            l2 = l2.next
        if flag:    # 当最高位向后一位进位时(需要添加节点时)
            p.next = ListNode(1)
        return l3

3.官方解法

  • 充分利用了python的语言特性
  • 不用考虑两个数的长度,可以将不等长转换为等长进行解决
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        head = ListNode(l1.val+l2.val)	# 建立结果列表
        cur = head	# 滚动指针
        while l1.next or l2.next:	# 当加法没有结束时
            l1 = l1.next if l1.next else ListNode()		# 遍历结束添加结点(根据结点定义默认为0)
            l2 = l2.next if l2.next else ListNode()
            cur.next = ListNode(l1.val + l2.val + cur.val // 10)	# 建立新结点,本位值相加+前一位的进位
            cur.val = cur.val % 10	# 原结点取余
            cur = cur.next	# 指针滚动
        if cur.val >= 10:	# 当最高位产生进位时
            cur.next = ListNode(cur.val // 10)	# 添加新结点
            cur.val = cur.val % 10	# 本位取余
        return head

上一篇:Jenkins Tips 002: 处理Shell返回字符串为数组


下一篇:深度学习之TensorFlow安装与初体验