class PalindromicLinkedList {
public static boolean isPalindrome(ListNode head) {
if (head == null || head.next == null)
return true;
// find middle of the LinkedList
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode headSecondHalf = reverse(slow); // reverse the second half
ListNode copyHeadSecondHalf = headSecondHalf; // store the head of reversed part to revert back later
ListNode start = head;
// compare the first and the second half
while (start != null && headSecondHalf != null) {
if (start.value != headSecondHalf.value) {
return false; // not a palindrome
}
start = start.next;
headSecondHalf = headSecondHalf.next;
}
reverse(copyHeadSecondHalf); // revert the reverse of the second half
return true;
}
private static ListNode reverse(ListNode head) {
ListNode prev = null;
while (head != null) {
ListNode next = head.next;
head.next = prev;
prev = head;
head = next;
}
return prev;
}
}
}
这是回文链接列表问题
给出单个LinkedList的头部,编写一种方法来检查 LinkedList是否是回文。
您的算法应使用恒定空间,算法完成后,输入LinkedList的格式应为原始形式。该算法应具有O(N)O(N)的时间复杂度,其中“ N”是LinkedList中的节点数。
以上代码是解决此问题的方法, 而且我了解其中的大部分内容,但很难理解
reverse(copyHeadSecondHalf);
我可能只是猜测这是针对算法条件的
算法完成后,输入LinkedList应该采用原始形式。
但是上面的代码, 我们是否曾经更改或修改过输入LinkedList? 每次我们定义新的ListNode指向头参考时 或其他一些。
同样,我们只有新变量“ headSecondHalf”具有新的反向版本LinkedList。 甚至我们在copyHeadSecondHalf上什么也没做。
但是我们为什么要拥有
reverse(copyHeadSecondHalf);
答案 0 :(得分:2)
但是上面的代码,我们是否曾经更改或修改过输入LinkedList?每次我们定义新的ListNode指向头参考或其他参考时。
是的,原始的LinkedList被修改了。
ListNode headSecondHalf = reverse(slow); // reverse the second half
以上行以LinkedList
的中间作为输入并将其反转。结果,LinkedList
的结构被更改。
例如:5→2→3→2 *→5 *
慢速指针位于位置3。
现在,headSecondHalf
指向5 *→2 *→3
由于反向操作,3指向NULL,因此原始列表变为5→2→3(仅列表的一半)。
同样,我们只有新变量“ headSecondHalf”具有新的反向版本LinkedList。甚至我们在copyHeadSecondHalf上什么也没做。
headSecondHalf
变量用于检查列表是否为回文。这意味着位置已更改。因此,该值将被复制到copyHeadSecondHalf
,然后再次反转该值,以便恢复原始列表。
答案 1 :(得分:0)
考虑以下链接列表示例
1->2->3->4->2'->1'->NULL
在第一个相反的情况下,我们得到一个新的链表,如下所示:
1'->2'->4->NULL
原始链接列表如下
1->2->3->4->NULL
比较之后,我们需要根据条件之一恢复链接列表。因此是相反的步骤。
但是,在代码中,虽然返回false,但没有执行最后一步,这违反了该规则。因此,您可以在返回前添加反向,或中断while循环,反向并在最后返回