一、问题描述
Given a singly linked list, determine if it is a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
二、问题分析
判断回文,一般操作都是一前一后两个指针,一块移动然后判断是否相等。但是对于链表来说尤其是单链表只能从前往后遍历而不能从后往前。当然如果不考虑空间复杂度,我们可以用一个栈来存储第一次遍历的Node,然后再遍历链表和栈;
如果优化到O(n) time and O(1) space,说明并没有一个像stack一样的存储结构来记录遍历过的值,那么只能是一边遍历一边比较,又因为单链表不能从后往前,所以可以结合之间做过的题,将链表翻转,当然不是从头,而是从中间;谈到中间,又要使用经典的slow fast指针来操作。
三、Java AC代码
public ListNode reverseList(ListNode head) {
if (head==null||head.next==null) {
return head;
}
ListNode pre = head,cur = head.next;
ListNode nxt = null;
pre.next = null;
while(cur != null){
nxt = cur.next;
cur.next = pre;
pre = cur;
cur = nxt;
}
return pre;
}
public boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) {
return true;
}
ListNode slower = head, faster = head;
while(faster!=null && faster.next!=null){
slower = slower.next;
faster = faster.next.next;
}
if (faster!=null) {
slower = reverseList(slower.next);
}else {
slower = reverseList(slower);
}
while (slower!=null) {
if (head.val==slower.val) {
head = head.next;
slower = slower.next;
}else {
return false;
}
}
return true;
}