image.png

解决思路

思想很很简单,用2个指针,一个low,一个fast,fast是low的2倍,所以可以达到2分链表的效果
,在移动指针时同时对前半部分链表进行反转。最后直接比较被分开的2个链表
因为不能改变当前slow的next,不然就无法跳到下一个元素,所以这里用pre和prepre实现指针的反转
时间复杂度:第一个循环O(n/2),第2个循环O(n/2)

code

  1. public boolean isPalindrome(ListNode head) {
  2. if(head == null || head.next == null) return true;
  3. ListNode slow = head, fast = head.next, pre = null, prepre = null;
  4. while(fast != null && fast.next != null) {
  5. //反转前半段链表
  6. pre = slow;
  7. slow = slow.next;
  8. fast = fast.next.next;
  9. //先移动指针再来反转
  10. pre.next = prepre;
  11. prepre = pre;
  12. }
  13. ListNode p2 = slow.next;
  14. slow.next = pre;
  15. //判断是否是奇数个节点
  16. ListNode p1 = fast == null? slow.next : slow;
  17. while(p1 != null) {
  18. if(p1.val != p2.val)
  19. return false;
  20. p1 = p1.next;
  21. p2 = p2.next;
  22. }
  23. return true;
  24. }