给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

节点Node类:
public class Node {
public int value;
public Node next;
public Node(int v) {
value = v;
}
}
遍历一遍链表使用栈保存链表数据,再遍历一遍链表,出栈数据和链表数据对比,到栈为空时,出栈数据都和链表数据相等,则为回文。
空间复杂度:O(n),时间复杂度:O(2n)
public static boolean isPalindrome1(Node head) {
Stack<Node> stack = new Stack<>();
Node cur = head;
while (cur != null) {
stack.push(cur);
cur = cur.next;
}
cur = head;
while (cur != null) {
if (cur.value != stack.pop().value) {
return false;
}
cur = cur.next;
}
return true;
}
遍历一遍链表找到中节点,再从中节点开始遍历链表的后半段,使用栈保存链表后半段数据;
再遍历一半链表,出栈数据和链表数据对比,到栈为空时,出栈数据都和链表数据相等,则为回文。
空间复杂度:O(n / 2),时间复杂度:O(2n)
public static boolean isPalindrome2(Node head) {
if (head == null || head.next == null) {
return true;
}
Node slow = head;
Node fast = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
Stack<Node> stack = new Stack<>();
while (slow != null) {
stack.push(slow);
slow = slow.next;
}
while (!stack.empty()) {
if (head.value != stack.pop().value) {
return false;
}
head = head.next;
}
return true;
}
<链表有偶数个节点时>)之后开始反转后半段的链表,记录下两段链表的起点;
空间复杂度:O(1),时间复杂度:O(2.5 * n)
public static boolean isPalindrome3(Node head) {
if (head == null || head.next == null) {
return true;
}
/**
* 1)反转链表中节点之后的链表段
*/
// n1 -> mid node
Node n1 = head;
Node n2 = head;
while (n2.next != null && n2.next.next != null) {
n1 = n1.next;
n2 = n2.next.next;
}
// n3 -> right part first node
Node n3 = n1.next;
n1.next = null;
while (n3 != null) {
// n2 -> save next node
n2 = n3.next;
// reverse
n3.next = n1;
n1 = n3;
n3 = n2;
}
// n2 / n1 -> save last node (reversed first node)
n2 = n1;
// n3 -> left first node
n3 = head;
/**
* 2)对比中节点之前的正常链表段 和 中节点之后反转的链表段。
*/
boolean res = true;
while (n1 != null && n3 != null) {
if (n1.value != n3.value) {
res = false;
break;
}
n1 = n1.next;
n3 = n3.next;
}
/**
* 3)还原head链表
*/
// n1 -> last node 's next node
n1 = n2.next;
// last node 'next to null
n2.next = null;
while (n1 != null) {
// n3 -> temp node for store "next" node
n3 = n1.next;
n1.next = n2;
// finally, n2 is mid
n2 = n1;
// finally, n1 / n3 is null
n1 = n3;
}
return res;
}
