当前位置: 首页 > 知识库问答 >
问题:

Java奇怪的NullPointerException在反转链接列表时

佴飞驰
2023-03-14

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

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

我的代码如下所示,测试的输入列表是1-

// 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;
    }    
}

输出(当输入为1时)-

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。瓦尔3岁。我不明白的是为什么两种制度。出来println(curr)给出不同的输出。curr不应该指最后一个节点吗?输出中的空值来自哪里?我认为这就是为什么会发生NullPointerException的关键。

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

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

共有2个答案

叶明辉
2023-03-14

也许,您应该使用Java公共集合中的iteratordowningiterator使用LinkedList实现您的isAlindrome方法:

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;
    }
蒯慈
2023-03-14

你的输入是1-

在进入while循环之前,您已经初始化了

curr=null;

你的程序在循环时进入

第一次迭代

>

1==3/2 1 false,输入else,如果再次为false,则转到else

第一次迭代后的值

m=1; curr=null prev=null and p=2(指向节点值2)

第二次迭代

>

2==3/2如果

上一个=1,当前

印钞。val为3,curr为打印“ListNode@77a567e1"

第二次迭代后的值

m=2;上一个=2,当前

第三次迭代

>

  • m=3

    3个

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

    温度=电流。next当curr为3时,next为空

    curr=temp; as temp=null curr is null

    第四次迭代

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

  •  类似资料:
    • 我正在尝试反转一个链表,我为此编写了代码。但是,当我在反转后打印列表时,输出有点不完整。 产量:120 110 100

    • 我目前无法获得双链接列表的反向函数来正确处理作业,我已经阅读了其他线程并在谷歌上搜索,但通常不同的是,我的问题以常量传递,它返回一个“dlist”。教授提供了一个“代码测试仪”,它说我的代码在执行“反向(反向(dlist c))”时,并不等于它本身就是“c”。[反转两次并不等于它本身]。 dlist类是: 这是反向函数: 每个数据列表节点都有一个指向前一个节点的指针和一个指向下一个节点的指针。dl

    • 我正在解决在给定大小的组中反转链表的问题,我使用的算法如下: 1) 反转大小k的第一个子列表。反转时,我跟踪下一个节点和上一个节点。将指向下一个节点的指针设为next,将指向前一个节点的指针设为prev 2)head=反向(下一个,k)-递归调用列表的其余部分 3) 返回prev,它是反向列表的新标题 我的代码示例是: 但我的输出只是颠倒了列表的前半部分! 例如:如果我的列表是:98 74 94

    • 我试图打印一个双链接列表,从tail元素开始,以first元素结束。我下面的代码就是这样做的,但出于某种原因,我也返回了被删除的项目。当我从头到尾打印列表时,它不会这样做。Idk,如果是toString导致了这个或dequed方法。我把两者都包括在内。

    • 问题内容: 请考虑以下代码片段: 据我所知(以及我的IDE可以告诉我的),变量和应该是等效的。 如您所料,我宁愿写最后2行而不是前7行。但是,当我向该方法传递3个空值时,在变量的计算上得到了NPE 。 有人知道这怎么可能吗?即使条件不满足,三元运算符也会评估第二部分吗? (Java版本1.6.0_21) 问题答案: 尝试: 要么 三元运算符的交替边的类型是和,这意味着将get取消装箱到,然后在赋值

    • 问题内容: 有人可以告诉我为什么我的代码有效吗?我想在Java中反转单个链接列表:这是方法(无法正常工作) 这是Node类: 在输入4-> 3-> 2-> 1上,我得到了输出4。我对其进行了调试,它正确设置了指针,但是我仍然不明白为什么它仅输出4。 问题答案: Node next = tmp.next; while(tmp != null){ 那么,当tmp == null时会发生什么呢? 不过,