繁体   English   中英

Java 反转链表时出现奇怪的 NullPointerException

[英]Java Weird NullPointerException When Reversing a Linked List

我正在研究一个名为“ Palindrome Linked List ”的 LeetCode 问题,其中给出了一个单链表,确定它是否是回文。 例如,如果输入为 1->2->2->1,则应为 output 为真。

我通过使用额外的空间(将列表转换为 ArrayList)解决了它,现在我试图通过另一种方法来解决它,反转列表的第二半,然后比较两半 虽然我可能没有以最好的方式实现这个想法,但我希望代码能够正常工作,或者 output 是错误的答案(然后我可以改进代码)。 然而,一个奇怪的 NullPointerException 发生了,我不知道为什么。

我的代码如下所示,测试的输入列表是 1->2->3 我还添加了一些打印来帮助调试。

// reverse the 2nd half of list and then compare the two halves

class Solution {
    public boolean isPalindrome(ListNode head) {
        int n = 0; // list length
        ListNode p = head;
        while (p != null) { // obtain list length n 
            n++;
            p = p.next;
        }
        p = head;


        int m = 0;
        ListNode prev = null, curr = null, temp = null;
        while (p != null) { // reverse the 2nd half of list
            m++;
            if (m == n/2 + 1) {
                prev = p;
                curr = p.next;
                p = p.next;

                System.out.println(curr.val);
                System.out.println(curr);
                //System.out.println(p);
            }
            else if (m > n/2 + 1) {
                //System.out.println(p);
                System.out.println(curr);
                //System.out.println(curr.val);

                temp = curr.next;
                curr.next = prev;
                prev = curr;
                curr = temp;
                p = p.next;
            }
            else 
                p = p.next;
        }


        int k = 1;
        while (k < n/2 + 1) { // compare the two halves, prev points at the last node
            if (head.val != prev.val)
                return false;
            head = head.next;
            prev = prev.next;
            k++;
        }
        return true;
    }    
}

output (输入1->2->3时,加上一些打印语句)为:

NullPointerException thrown at the line: temp = curr.next; (which is inside the else if)

the code also prints:
3
ListNode@77a567e1
ListNode@77a567e1
null 

curr 是指最后一个节点,所以 curr.val 是 3。我不明白为什么两个 System.out.println(curr)给出不同的输出。 curr 不应该指的是最后一个节点吗? output中的null是哪里来的? 我认为这是 NullPointerException 发生在那里的关键。

我现在很困惑,如果有人可以帮助我理解出了什么问题,我将非常感激。 谢谢。

编辑:由于这是一个 LeetCode 问题,所以 ListNode class 是预定义的,我不需要自己编写。

也许,您应该使用iteratordescendingIterator使用 Java common Collections 中的LinkedList实现您的isPalindrome方法:

LinkedList<Integer> list = new LinkedList<>(Arrays.asList(1, 2, 3));
System.out.printf("list: %s palindrome: %s%n", list,  isPalindrome(list));
// ...

  public boolean isPalindrome(LinkedList<Integer> list) {
    Iterator<Integer> directIterator = list.iterator();
    Iterator<Integer> reverseIterator = list.descendingIterator();
    int count = list.size() / 2;
    while (directIterator.hasNext() && reverseIterator.hasNext() && count-- > 0) {
      if (directIterator.next().intValue() != reverseIterator.next().intValue()) {
        return false;
      }
    }
    return true;
  }

更新:使用反向列表的请求单链表的解决方案:

    public boolean isPalindrome(ListNode head) {
        // empty and single element list is palindrome
        if (null == head || null == head.next) {
            return true;
        }
        // build reverse linked list
        ListNode curr = head;
        ListNode tail = new ListNode(curr.val);
        tail.next = null;
        ListNode prev = null;
        int size = 1;
        while (null != curr.next) {
            prev = tail;
            curr = curr.next;
            tail = new ListNode(curr.val);
            tail.next = prev;
            size++;
        }
        // move both from head and from tail to the middle element
        int half = size / 2;
        curr = head;
        prev = tail;
        while (null != curr && null != prev && half-- > 0) {
            if (curr.val != prev.val) {
                return false;
            }
            curr = curr.next;
            prev = prev.next;
        }
        return true;
    }

你给定的输入是 1->2->3 所以你的 n 是 3。

在进入你已经初始化的while循环之前

当前= null;

你的程序进入while循环

第一次迭代

  • 米++; m=1 的值

  • 1 == 3/2+1 false 所以输入 else if 再次为 false 所以转到 else

第一次迭代后的值

米 = 1; curr=null prev=null 和 p=2(指向节点值 2)

第二次迭代

  • m=2

  • 2 == 3/2+1 true 进入 if

  • prev = 1, curr & p = 3(值为 3 的节点)

  • 打印 curr.val 为 3 和 curr 打印“ListNode@77a567e1”

第二次迭代后的值

米 = 2; prev=2, curr & p=3(值为 3 的节点)

第三次迭代

  • 米=3

  • 3>3/2+1 true 所以进入 else if

  • 打印当前打印“ListNode@77a567e1”

  • temp = curr.next 因为 curr 是 3 它的下一个是 null

  • 当前=温度; 因为 temp = null curr 是 null

第四次迭代

so as curr is null on forth iteration it prints null and throws null pointer exception.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM