【问题标题】:Add two numbers problem (linked list) - Python - Leetcode - AttributeError两个数字相加问题(链表) - Python - Leetcode - AttributeError
【发布时间】:2020-04-16 06:58:07
【问题描述】:

我正在尝试解决这个问题 - 添加两个位于 Leetcode 上的数字

我尝试将两个链表都转换为数组,然后执行添加操作。现在,我正在努力将它们转换回链接列表,这是问题所需的输出。

谁能检查我哪里出错了?我也收到一个属性错误:

AttributeError: 'NoneType' 对象没有属性 'val'

这是我写的代码:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
  def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
    a = l1 #pointers
    b = l2 #pointers
    arr1 = []
    arr2 = []

    while a.next is not None:
      arr1.append(a.val)
      a = a.next
    arr1.append(a.val) #storing the values of linked lists in arrays/lists

    while b.next is not None:
      arr2.append(b.val)
      b = b.next
    arr2.append(b.val) #storing the values of linked lists in arrays/lists

    rev1 = reversed(arr1) #reversed list
    rev2 = reversed(arr2) #reversed list

    inta = "".join(str(rev1)) #converting list to strings
    intb = "".join(str(rev2))

    c = str(inta + intb) #performing addition - the answer we wanted
    revc = reversed(c) #answer in string form - reversed (output in string at present)

    #trying to convert into linked list and return it
    q = l1
    for i in revc:
      q.val = i
      q = q.next
    return l1

【问题讨论】:

    标签: python-3.x list data-structures linked-list attributeerror


    【解决方案1】:
    class Solution:
    
        
        def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        carry = 0
        head = curr = ListNode()
            
        while l1 and l2:
            total = l1.val + l2.val + carry
            curr.next = ListNode(total% 10)
            carry = total // 10
            l1,l2,curr = l1.next, l2.next,curr.next
                
        while l1:
            total = l1.val + carry
            curr.next = ListNode(total%10)
            carry = total // 10
            l1, curr = l1.next, curr.next
                
        while l2:
            total = l2.val + carry
            curr.next = ListNode(total%10)
            carry = total//10
            l2, curr = l2.next, curr.next
        if carry > 0:
            curr.next  = ListNode(carry)
                    
        return head.next
    

    【讨论】:

    【解决方案2】:

    我是在 Python3 中完成的,我建议你在 Python3 中工作。

    对于逆向操作,您也可以使用就地的.reverse(),这样您就不必创建新变量。

    另外,您的.join() 操作不正确。您需要遍历每个列表中的每个字符,而不是您正在做的事情是制作列表的字符串表示形式。

    返回的链表的构造包括为该链表的头部分配一个值,然后在遍历结果字符串时根据需要在新的 ListNodes 中添加数字。

    我应该说,虽然我相信您的解决方案是一个新颖的解决方案,但我认为问题的精神是让您更轻松地使用链表。因此,我认为,围绕它们工作有点违背这个目标。

    话虽如此,这是一个非常节省内存的解决方案,因为列表是 Python 中非常优化的数据结构。

    祝您编码愉快!

    class Solution:
        def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
            a = l1 #pointers
            b = l2 #pointers
            arr1 = []
            arr2 = []
    
            while a:
              arr1.append(a.val)
              a = a.next
    
            while b:
              arr2.append(b.val)
              b = b.next
    
            arr1.reverse()
            arr2.reverse()
    
            inta = int("".join(str(x) for x in arr1)) #converting list to strings
            intb = int("".join(str(x) for x in arr2))
    
            c = list(str(inta + intb)) #performing addition - the answer we wanted
    
            # assign last digit to new ListNode which represents the head of returned LL
            head = l3 = ListNode(c.pop())
    
            c.reverse()
    
            # traverse remaining digits, assigning each to new ListNode
            for i in c:
                l3.next = ListNode(i)
                l3 = l3.next
    
            return head 
    

    【讨论】:

      【解决方案3】:

      NoneType 表示您正在使用None,您应该在其中使用类或对象的实例。当上面的赋值或函数调用失败或返回意外结果时,就会发生这种情况。

      NoneType 是值None 的类型。在这种情况下,变量生命周期的值为None。通常发生的是调用缺少返回的函数。

      【讨论】:

        【解决方案4】:

        您的错误是因为当您尝试访问.val 时,abqNone

        我不打算找出原因,而是解释你应该如何尝试解决这个问题。


        这样指定问题的原因是您可以编写一个有效的解决方案。问题提示您从基本单位编写长加法 - 即单位、十、百、千等。

        数字是相反的,所以你可以从单位开始,携带超过 10 的任何东西。

        243
        564
        ^
        start here
        
        2 + 5 = 7, carry 0
        
        243
        564
         ^
        
        4 + 6 = 0, carry 1
        
        243
        564
          ^
        
        3 + 4 (+ 1) = 8, carry 0
        
        therefore the answer is 
        
        7 -> 0 -> 8
        

        这样思考意味着您可以编写更有效的响应。这方面的复杂性是O(max(len(a), len(b))),而对于您的方法来说,它大约是O(8*max(len(a), len(b)))。差别不大,但计算量很大,而且不容易理解。

        我确信这里可以进行合乎逻辑的改进,但这是我认为您应该瞄准的解决方案:

        class Solution:
            def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
                carry = 0
                original = value = ListNode(None)
                while True:
                    if l1 is None and l2 is None:
                        value.val = carry
                        break
                    elif l1 is None:
                        value.val = l2.val + carry
                        carry = 0
                        l2 = l2.next
                    elif l2 is None:
                        value.val = l1.val + carry
                        carry = 0
                        l1 = l1.next
                    else:
                        car, val = divmod(l1.val + l2.val, 10)
                        value.val = val + carry
                        carry = car
                        l1, l2 = l1.next, l2.next
                    value.next = ListNode(None)
                    value = value.next
                return original
        

        编辑:经过进一步思考,我意识到您也可以通过递归很好地做到这一点。

        class Solution:
            def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
                def recursive_wrapper(l1, l2, carry):
                    if l1 is None and l2 is None:
                        return None
                    elif l1 is None:
                        res = ListNode(l2.val + carry)
                        res.next = add_two_recursive(None, l2.next, 0)
                    elif l2 is None:
                        res = ListNode(l1.val + carry)
                        res.next = add_two_recursive(l1.next, None, 0)
                    else:
                        car, val = divmod(l1.val + l2.val, 10)
                        res = ListNode(val + carry)
                        res.next = add_two_recursive(l1.next, l2.next, car)
                    return res
                return recursive_wrapper(l1, l2, 0)
        

        您可以随时创建ListNode。在每一点,它都是l1 的头部加上l2 的头部加上作为值的携带号。然后为l1l2 获取下一个并重复。如果在任何时候缺少l1l2,则将该值计为0。一旦没有更多数字,返回 None 表示结果结束。

        【讨论】:

          猜你喜欢
          • 2021-08-20
          • 2021-12-29
          • 1970-01-01
          • 2018-05-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-06-12
          • 1970-01-01
          相关资源
          最近更新 更多