题目描述:
给定一个链表的 头节点 head ,请判断其是否为回文链表。
如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。
方法一:
思路: 首先使用快慢指针找到链表中间的节点,之后从中间节点开始依次压栈,直到末尾。最后将栈中的每一个元素弹出和正向遍历链表的元素比较看是否相等,若有一个不相等,则直接返回false。
class Solution {
public boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) {
return true;
}
ListNode pre = head;
ListNode last = head;
Stack<ListNode> stack = new Stack<>();
while (last.next != null && last.next.next != null) {
pre = pre.next;
last = last.next.next;
}
pre = pre.next;
while (pre != null) {
stack.push(pre);
pre = pre.next;
}
pre = head;
while (!stack.isEmpty()) {
ListNode node = stack.pop();
if (pre.val != node.val) {
return false;
}
pre = pre.next;
}
return true;
}
}
方法二:
思路: 使用快慢指针,在快指针走完时满指针会走到中间的位置,之后,从慢指针只想中间节点的位置开始将链表剩余的部分反转。比较晚每个元素之后再将反转的链表恢复。
class Solution {
public boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) {
return true;
}
// 找到中间节点
ListNode pre = head;
ListNode last = head;
while (last.next != null && last.next.next != null) {
pre = pre.next;
last = last.next.next;
}
// 从中间节点以后讲链表逆序
last = pre.next;
pre.next = null;
ListNode temp = null;
while (last != null) {
temp = last.next;
last.next = pre;
pre = last;
last = temp;
}
// 此时pre指向原来链表的最后一个节点, 使用temp保留
temp = pre;
last = head;
while (pre != null && last != null) {
if (pre.val != last.val) {
return false;
}
pre = pre.next;
last = last.next;
}
// 恢复原来的链表
pre = temp;
temp = null;
while (pre != null) {
last = pre.next;
pre.next = temp;
temp = pre;
pre = last;
}
return true;
}
}