Given a singly linked list, determine if it is a palindrome.
Example 1:
Input: 1->2
Output: false
Example 2:
Input: 1->2->2->1
Output: true
Follow up:
Could you do it in O(n) time and O(1) space?
my solution
public boolean isPalindrome(ListNode head) {
if(head == null || head.next==null) return true;
if(head.next.next==null) return head.val==head.next.val;
ListNode slow = head;
ListNode fast = head;
int n = 0;
//找到链表的中间节点,然后反转链表的后半部分,最后从head开始比较
while(fast.next!=null)
{
fast = fast.next;n++;
if(fast.next!=null)
{
fast= fast.next; n++;
}
slow = slow.next;
}
//反转slow;
if(n%2==0)
slow = reverseList(slow.next);
else
slow = reverseList(slow);
while(slow!=null)
{
if(slow.val!=head.val) return false;
slow= slow.next;
head = head.next;
}
return true;
}
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode p = reverseList(head.next);
head.next.next = head;
head.next = null;
return p;
}
改进:在找中间节点时,对链表前半部分进行原地反转
public boolean isPalindrome(ListNode head)
{
if(head == null ||head.next == null) return true;
ListNode slow = head;
ListNode fast = head;
ListNode reverse = head;//表示前半部分反转后链表的表头
ListNode tmp;
while(fast!=null && fast.next!=null)
{
fast = fast.next.next;
//边移动边反转链表,原地反转
tmp = slow;
slow = slow.next;
tmp.next = reverse;
reverse = tmp;
}
if(fast != null) slow = slow.next;
while(slow!=null)
{
if(slow.val!=reverse.val) return false;
slow= slow.next;
reverse = reverse.next;
}
return true;
}