回文链表
题目描述
请判断一个链表是否为回文链表。
请采用 O(n) 的时间复杂度和 O(1) 的空间复杂度进行求解。
题目分析
如果是数组,很显然采用双指针,分别从前和后两段同时遍历即可
但是链表面临着两个问题
1、链表的长度
2、单链表,没有从后向前遍历的方法
那么需要解决这两个问题
1、首先需要查找到链表的中间节点 (快慢双指针,快指针每次走两个节点,慢指针每次走一个节点)
2、从中间节点到尾结点进行逆序 (头插法,辅助空间为 O(1) )
class Solution { //本质上是,将从中间节点之后节点反转,把中间节点作为两个头指针所指向链表的终点 public boolean isPalindrome(ListNode head) { if (head == null || head.next == null) { return true; } ListNode mid = generateMid(head); ListNode subHead = reverse(mid); //遍历 while (subHead != null) { if (subHead.val != head.val) { return false; } subHead = subHead.next; head = head.next; } return true; } //反转链表 private ListNode reverse(ListNode head) { ListNode pre = null; ListNode cur = head; while (cur != null) { ListNode tmp = cur.next; cur.next = pre; pre = cur; cur = tmp; } return pre; } //奇数寻找中间节点,或者偶数右中位数节点 private ListNode generateMid(ListNode head) { ListNode slow = head; ListNode fast = head; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } return slow; } }