【问题标题】:linked list while statement (addTwoNumbers from LeetCode)链表 while 语句(来自 LeetCode 的 addTwoNumbers)
【发布时间】:2019-12-04 02:18:38
【问题描述】:

以下是我提交并随后被接受的代码。

class Solution(object):
def addTwoNumbers(self, l1, l2):
    """
    :type l1: ListNode
    :type l2: ListNode
    :rtype: ListNode
    """
    result = ListNode(0)
    result_tail = result
    carry = 0

    while l1 or l2 or carry:        

        val1  = (l1.val if l1.val else 0)
        val2  = (l2.val if l2.val else 0)

        out = (val1+val2 + carry)%10
        carry = (val1+val2 + carry)//10

        result_tail.next = ListNode(out)
        result_tail = result_tail.next                      

        l1 = (l1.next if l1.next else None)
        l2 = (l2.next if l2.next else None)

    return result.next 

最初,我有while l1.val or l2.val or carry:,但它被拒绝并显示以下错误消息:

AttributeError: 'NoneType' 对象具有 njo 属性 'val'

但是,链接节点列表 l1 和 l2 显然具有属性 val 和 next。

我不确定为什么while l1.val or l2.val or carry: 不起作用。

以下是我最初提交但被拒绝的代码。

class Solution(object):
def addTwoNumbers(self, l1, l2):
    """
    :type l1: ListNode
    :type l2: ListNode
    :rtype: ListNode
    """
    result = ListNode(0)
    result_tail = result
    carry = 0

    print(l1.val)
    print(l2.val)
    while l1.val or l2.val or carry:        

        val1  = (l1.val if l1.val else 0)
        val2  = (l2.val if l2.val else 0)

        out = (val1+val2 + carry)%10
        carry = (val1+val2 + carry)//10

        result_tail.next = ListNode(out)
        result_tail = result_tail.next                      

        l1 = (l1.next if l1.next else None)
        l2 = (l2.next if l2.next else None)

    return result.next 

【问题讨论】:

    标签: python singly-linked-list


    【解决方案1】:

    因为l1l2NoneType,或者本质上是None,这意味着它们实际上不是您所期望的类型。 None 怎么进来的?好吧,两种方法之一:

    首先,有人可以传入None 作为输入,l1l2

    第二个,几乎可以肯定是你的问题,它来自以下陈述:

            l1 = (l1.next if l1.next else None)
            l2 = (l2.next if l2.next else None)
    

    换句话说,如果没有下一个值,我们将确保将其设置为无。然后,因为我们在l1 or l2 or carry 的条件下循环,所以其中只有一个必须是“真实的”。换句话说,l1 可能是 None,l2 是下一次迭代的有效列表,反之亦然……或者进位是真实的。或两者兼而有之。

    您的条件l1 or l2 or carry 的真值表以更好地可视化:

    l1 | l2 | carry | result
    ------------------------
    T---T----T------|   T
    T---F----T------|   T
    T---T----F------|   T
    T---F----F------|   T
    F---T----T------|   T
    F---F----T------|   T
    F---T----F------|   T
    F---F----F------|   F
    

    由于None 是“假”类型,None 的计算结果为False,但是这三个条件都为False 才能不继续循环。

    至于开头的打印,它们是 before while 循环,因此每次迭代该循环时,l1l2 都会得到不同的值。您已确定传入的不是None。但这并没有阻止l1l2 以后变成None

    【讨论】:

    • 我看到了我的解决方案的潜在问题。但是,对于特定的测试用例,我确实尝试了 'print(l1.val) print(l2.val)' 以确保测试用例没有通过 'None'
    • @stratofortress 你的印刷声明在哪里?你确定你不只是打印val1val2?如果您在访问它们之前打印了l1l2,那么您会看到一个None 值,如果您在它崩溃之前打印它。简单明了。
    • 再次感谢您的评论。我刚刚在我接受的代码下方添加了原始提交。我打印了 l1.val 和 l2.val 以确保它们不是“无”
    • @stratofortress 我在答案中附加了更多信息。您在 while 循环之前打印了 None。打印一次,while 循环可以无限执行,每次运行时修改l1l2
    【解决方案2】:

    可能有一个测试用例,其中 l1 和/或 l2 的传入值为 None。如果发生这种情况,则会引发 AttributeError,因为 None 没有任何此类属性 - 它只是 None(在其他语言中为 null)。

    请注意,您通过简单地从 while 语句中的每个 l1 和 l2 中删除 .val 来解决了检查 None 的问题。这就是第二次提交成功接受的原因。

    【讨论】:

    • 你认为它应该有效吗?我查看了测试用例,我认为 l1 或 l2 都没有通过。
    • 即使 l1 或 l2 的测试用例都没有通过 None,最好仍然检查所有用例。也可能存在这样一种情况,即在循环内部,更新后 l1 或 l2 变为 None,再次证明需要处理 l1 和/或 l2 为 None 的情况。注意:当您将代码更改为 l1 或 l2 而不是 l1.val 或 l2.val 时,您实现了这一点
    猜你喜欢
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 2016-02-29
    • 2022-01-17
    • 2012-06-14
    • 1970-01-01
    相关资源
    最近更新 更多