判断一个链表是否为回文链表。
提示:空链表和只有一个元素都是回文链表
代码片
.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
//暴力方法1:
//原理:
//因为回文链表翻转后与之前的链表一样,所以只需要将翻转的链表与原链表进行比较即可
//如果两个链表相同,就是回文链表
//这个方法只需要使用下面的翻转函数即可,直接将整个链表翻转,然后一一比较节点。无需找中点
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//方法2:
//先找到中点,利用迭代翻转法或者递归法,将中点以后的节点翻转,然后从头节点和中节点开始比较
//全部一样就是回文链表,反之不是
//如果只有一个节点或者没有节点,那就直接返回true
if (head == null || head.next == null) {
return true;
}
//找到中点
//例如:1,2,3,4,5,6,7,8,9
//mid的路程1,2,3,4,5
//end的路程1,3,5,7,9
//mid一次走移位,end一次走两位,当end走到链表最后,mid刚好是链表的中点
ListNode mid=head;
ListNode end=head;
//例如:1,2,3,4,5,6,7,8,9,10
//当链表节点个数是偶数时,就要需要判断end.next.next是否为空
while(end.next!=null&&end.next.next!=null){
end=end.next.next;
mid=mid.next;
}
//第2步:翻转链表
//迭代法
//链表: null -> 1 -> 2 ->3->4->5
// prev -> now -> next ->
/*
ListNode prev=null;
ListNode now=mid.next;
ListNode next=null;
while(now!=null){
next=now.next;//保存下一个节点 这时链表的情况是 // 1->2
//2->3->4->5
now.next=prev;//将2的下个节点指向1 这时链表的情况是://2->1
//2->3->4->5
prev=now;将现在的节点变为前一个节点 //2->1
// prev -> now -> next
now=next; //将下一个节点变为当前节点 // 3 -> 4 ->5
// now -> next
}
mid=prev;
*/
//第2步:递归法翻转链表
//递归法
mid=reverse(mid.next);
//第3步:对比翻转后的链表
while(mid!=null){
if(mid.val!=head.val){
return false;
}
mid=mid.next;
head=head.next;
}
return true;
}
//递归函数
public ListNode reverse(ListNode head){
if(head.next==null){
return head;
}
ListNode newHead=reverse(head.next);
head.next.next=head;
head.next=null;
return newHead;
}
}