[英]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 是预定义的,我不需要自己编写。
也许,您应该使用iterator
和descendingIterator
使用 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.