思路:
1、遍历整个链表,将链表每个节点的值记录在数组中,再判断数组是不是一个回文数组,时间复杂度为O(n),但空间复杂度也为O(n),不满足空间复杂度要求。
2、利用栈先进后出的性质,将链表前半段压入栈中,再逐个弹出与链表后半段比较。时间复杂度O(n),但仍然需要n/2的栈空间,空间复杂度为O(n)。
3、反转链表法,将链表后半段原地翻转,再将前半段、后半段依次比较,判断是否相等,时间复杂度O(n),空间复杂度为O(1)满足题目要求。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isPalindrome(ListNode head) {
if (head == null || head.next == null)
return true;
ListNode p1 = head;
ListNode p2 = head;
ListNode pre = null;
while (p2 != null && p2.next != null) { //快速找到链表中间
pre = p1;
p1 = p1.next;
p2 = p2.next.next;
}
pre.next = null; //前半部分的链表与后半部分的链表断开
p2 = p1.next; //p1指向后半部分链表的表头,p2指向表头的下一个节点
ListNode newHead = p1; //newHead为后半部分链表原地翻转后的表头
while (p2 != null) { //原地翻转后半部分链表
p1.next = p2.next;
p2.next = newHead;
newHead = p2;
p2 = p1.next;
}
p1 = head;
p2 = newHead;
while (p1 != null) { //判断前后半部分的链表元素是否对应相等
if (p1.val != p2.val)
return false;
p1 = p1.next;
p2 = p2.next;
}
return true;
}
}
Runtime:2ms