题目描述:
给定一个链表的头结点head,判断该链表是否为回文结构。
例如:
1->2->1,返回false
1-2->2->1,返回true
15->6->15,返回true
1->2->3,返回false
要求:如果链表的长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1)
思路:设计两个指针,快指针一次走两步,慢指针一次走两步,然后从当快指针的下一个节点或下下一个节点为空停,将慢指针以后的节点反转,然后将左边未反转的部分和右部分反转的部分进行比较,如果每个数都相等,则是回文链表,否则不是,最后在将链表修改成原来的结构,也就是将反转的部分链表,在反转回去
public class Code_013_IsPalindromeList {
public static class Node {
public int data;
public Node next;
public Node(int data) {
this.data = data;
}
}
public static boolean isPalindrome(Node head) {
if (head == null || head.next == null) {
return true;
}
Node n1 = head;
Node n2 = head;
while(n2.next != null && n2.next.next != null) {
n1 = n1.next;
n2 = n2.next.next;
}
//反转后部分链表
Node n3 = null;
while(n1 != null) {
n2 = n1.next;
n1.next = n3;
n3 = n1;
n1 = n2;
}
boolean res = true;
n1 = head;
n2 = n3;//保存反转后的链表的头结点
//n3是从右往左链表的头结点,判断是不是回文链表
while(n1 != null) {
if (n1.data != n3.data) {
res = false;
break;
}
n1 = n1.next;
n3 = n3.next;
}
//调整回原链表结构,n2是反转后的链表的头结点
n3 = null;
while(n2 != null) {
n1 = n2.next;
n2.next = n3;
n3 = n2;
n2 = n1;
}
return res;
}
}