Leetcode#2,检测到循环错误

问题描述

我正在尝试解决leetcode#2,为您提供了两个表示两个非负整数的非空链表。这些数字以相反的顺序存储,并且它们的每个节点都包含一个数字。将两个数字相加,然后将其作为链表返回。

您可以假定两个数字除了数字0本身以外,都不包含任何前导零。 https://leetcode.com/problems/add-two-numbers/ 我收到错误消息:周期仅检测到一位数字的加法。 我在做什么错了?

class Solution {
  public ListNode addTwoNumbers(ListNode l1,ListNode l2) {
    ListNode newpointer = null,mover = null;
    ListNode p = l1,q = l2;
    int carry = 0;
    while (p != null || q != null) {
      int x = (p == null) ? 0 : p.val;
      int y = (q == null) ? 0 : q.val;
      int sum = carry + x + y;
      carry = sum / 10;
      int digit = sum % 10;
      ListNode newnode = new ListNode();
      newnode.val = digit;
      newnode.next = null;
      if (newpointer == null) {
        newpointer = newnode;
        mover = newpointer;
      }
      mover.next = newnode;
      mover = mover.next;

      if (p != null) p = p.next;
      if (q != null) q = q.next;
    }
    if (carry > 0) {
      mover.next = new ListNode(carry);

    }

    return newpointer;
  }
}

解决方法

您的代码段中包含以下行:

ListNode newnode = new ListNode();
...
if (newpointer == null) {
    newpointer = newnode;
    mover = newpointer;
}
mover.next = newnode;

这会使LC循环检测算法产生问题。

如果考虑到while循环的第一次运行,您会发现mover指向与newnode相同的对象。

换句话说,对象ListNode newnode = new ListNode();mover.next = newnode;之后以其自身的循环边缘结束。

,

似乎有一些多余的指针和检查。因为它们的顺序相反,所以自然是求和的顺序。我认为我的代码可以自我解释,但是如果您有任何问题,请告诉我。

public ListNode addTwoNumbers(ListNode l1,ListNode l2) {
    ListNode head = null;
    ListNode prev = null;
    int carry = 0;
    while (l1 != null && l2 != null) {
        final int sum = l1.val + l2.val + carry;
        ListNode cur = new ListNode(sum % 10);
        carry = sum / 10;
        if (head == null) {
            head = cur;
        } else {
            prev.next = cur;
        }
        l1 = l1.next;
        l2 = l2.next;
        prev = cur;
    }
    ListNode remaining = l1 == null ? l2 : l1;
    while (remaining != null) {
        int sum = remaining.val + carry;
        ListNode cur = new ListNode(sum % 10);
        carry = sum / 10;
        prev.next = cur;
        remaining = remaining.next;
        prev = cur;
    }
    if (carry > 0) {
        prev.next = new ListNode(carry);
    }
    return head;
}
,

正在接受的答案中似乎已经找到了您遇到的错误,但是如果您愿意的话,我们可以稍微简化一下语句来解决该问题,使其更具可读性和理解性。

public final class Solution {
    public static final ListNode addTwoNumbers(
        ListNode l1,ListNode l2
    ) {
        int carry = 0;
        final ListNode sentinel = new ListNode(0);
        ListNode tail = sentinel;

        while (!(l1 == null && l2 == null && carry == 0)) {
            final int add1 = l1 != null ? l1.val : 0;
            final int add2 = l2 != null ? l2.val : 0;
            final int sum = add1 + add2 + carry;
            carry = sum / 10;
            final ListNode tempNode = new ListNode(sum % 10);
            tail.next = tempNode;
            tail = tempNode;

            if (l1 != null) {
                l1 = l1.next;
            }

            if (l2 != null) {
                l2 = l2.next;
            }

        }

        return sentinel.next;
    }
}

我们在这里使用Sentinel Node


参考文献

  • 有关其他详细信息,请参见Discussion Board,在这里您可以找到许多具有各种languages且已被广泛接受的解决方案,包括低复杂度算法和渐近runtime / {{ 3}}分析memory1