Implement a function to check if a linked list 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?
Solutions
Solution 1: Fast and Slow Pointers + Reverse List
First, we check if the list is empty. If it is, we return true directly.
Next, we use fast and slow pointers to find the midpoint of the list. If the length of the list is odd, the slow pointer points to the midpoint. If the length of the list is even, the slow pointer points to the first of the two middle nodes.
Then, we reverse the list after the slow pointer, giving us the second half of the list, with the head node as $p$.
Finally, we loop to compare the first half and the second half of the list. If there are any unequal nodes, we return false directly. Otherwise, we return true after traversing the list.
The time complexity is $O(n)$, where $n$ is the length of the list. The space complexity is $O(1)$.
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */funcisPalindrome(head*ListNode)bool{ifhead==nil{returntrue}slow,fast:=head,head.Nextforfast!=nil&&fast.Next!=nil{slow,fast=slow.Next,fast.Next.Next}p:=slow.Nextslow.Next=nildummy:=&ListNode{}forp!=nil{next:=p.Nextp.Next=dummy.Nextdummy.Next=pp=next}p=dummy.Nextforp!=nil{ifhead.Val!=p.Val{returnfalse}head=head.Nextp=p.Next}returntrue}
/** * Definition for singly-linked list. * public class ListNode { * public int val; * public ListNode next; * public ListNode(int x) { val = x; } * } */publicclassSolution{publicboolIsPalindrome(ListNodehead){if(head==null){returntrue;}ListNodeslow=head;ListNodefast=head.next;while(fast!=null&&fast.next!=null){slow=slow.next;fast=fast.next.next;}ListNodep=slow.next;slow.next=null;ListNodedummy=newListNode(0);while(p!=null){ListNodenext=p.next;p.next=dummy.next;dummy.next=p;p=next;}p=dummy.next;while(p!=null){if(head.val!=p.val){returnfalse;}head=head.next;p=p.next;}returntrue;}}