题目
请判断一个链表是否为回文链表。空间复杂度为O(1)
思路
快慢指针,快指针一次走两步,慢指针一次走一步。
快指针走到终点时,慢指针刚好走到链表中间。
反转后半部分链表,与前半部分链表的节点值一一比较,相同则是回文,然后将反转的链表恢复。
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
public boolean isPalindrome(ListNode head) {
if(head == null || head.next == null){
return true;
}
//快慢指针找到中间节点
ListNode fast = head;
ListNode slow = head;
//这里巧妙的利用fast.next.next判空,实现无论链表奇偶,slow都指向前半部分链表最后一个节点
while(fast.next!= null && fast.next.next!= null){
fast = fast.next.next;
slow = slow.next;
}
//反转后半部分
ListNode newList = reverseListNode(slow.next);
ListNode first = head;
ListNode second = newList;
boolean res = true;
while(second != null){
if(first.val != second.val){
res = false;
}
first = first.next;
second = second.next;
}
//恢复链表
ListNode node = reverseListNode(newList);
//串联前后两个链表
slow.next = node;
return res;
}
//反转链表模版
public ListNode reverseListNode(ListNode node){
ListNode prev = null;
ListNode curr = node;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
}
}