题目描述
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
解题思路
方法一:快慢指针
- 通过快慢指针找到链表的中心节点
- 反转链表的后半部分
- 判断链表是否回文
- 恢复链表后半部分
- 返回结果
代码
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var isPalindrome = function (head) {
if (!head) return true;
// ? 1. 找到链表的中心,通过快慢指针
const endOfFirstHalf = head => {
let fast = head;
let slow = head;
while (fast.next && fast.next.next) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
};
// ? 2. 反转后半部分的链表
const reverseList = head => {
let pre = null;
let cur = head;
while (cur) {
let next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
};
let firstHalfEnd = endOfFirstHalf(head);
let secondHalfStart = reverseList(firstHalfEnd.next);
// 3. 判断链表是否回文
let p1 = head;
let p2 = secondHalfStart;
let result = true;
while (p2 !== null && result) {
if (p1.val !== p2.val) {
result = false;
}
p1 = p1.next;
p2 = p2.next;
}
// 4. 恢复链表的后半部分
firstHalfEnd.next = reverseList(secondHalfStart);
return result;
};