题目描述
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针head,请返回一个bool值,代表其是否为回文结构。
思路:
- 由于是单链表,结点没有指向前一个结点的引用,因此需要将后半部分链表反转。
- 定义两个引用,一个在链表头从前向后走, 另一个在链表尾从后向前走。
- 每走一步判断两个结点的值是否相同,直到两个引用相遇。
图解:
代码实现:
public class PalindromeList {
public boolean chkPalindrome(ListNode head) {
//找链表中点
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
}
//此时slow位于链表中间,开始反转链表slow后面的部分
ListNode p = slow.next;
ListNode pNext = p.next;
while(p != null){
p.next = slow;
slow = p;
p = pNext;
if(pNext != null){
pNext = pNext.next;
}
}
//此时链表后半部分反转完毕,开始判断是否为回文结构
while(head != slow){
if(head.val != slow.val){
return false;
}
//处理链表个数为偶数的情况
if(head.next == slow){
return true;
}
head = head.next;
slow = slow.next;
}
return false;
}
}