思路:
先通过快慢指针找到中间节点,把后半部分的链表翻转,再和前半部分的链表进行值比较,比较完后将后半部分的链表再翻转回来
代码:
class Solution {
public boolean isPalindrome(ListNode head) {
if(head==null){
return true;
}
ListNode tail=endOfHead(head);
ListNode second=reverseList(tail.next);
boolean res=true;
ListNode p1=head;
ListNode p2=second;
while(res&&p2!=null){
if(p1.val!=p2.val){
res=false;
}
p1=p1.next;
p2=p2.next;
}
tail.next=reverseList(second);
return res;
}
private ListNode endOfHead(ListNode head){
ListNode slow=head;
ListNode fast=head;
while(fast.next!=null&&fast.next.next!=null){
fast=fast.next.next;
slow=slow.next;
}
return slow;
}
private ListNode reverseList(ListNode node){
ListNode pre=null;
ListNode cur=node;
while(cur!=null){
ListNode next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
return pre;
}
}
分解:
1)通过快慢指针找到中间节点:
快指针每次走2步,慢指针每次走1步,则快指针到达链表尾的时候,慢指针刚好在中间节点处,如果是奇数,中间节点在前半部分链表中
2)对后半部分链表进行翻转(略)
3)翻转后的链表与前半部分链表进行值比较,比较完后还要将后半部分的链表翻转回来
复杂度分析:
时间复杂度:O(N)遍历了几次,但每次的时间复杂度都是O(N)
空间复杂度:O(1)指针只占常数级复杂度