LeetCode 234. 回文链表|刷题打卡

272 阅读1分钟

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false

示例 2:

输入: 1->2->2->1
输出: true

进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

解题思路

官方题解

方法一:快慢指针

  1. 通过快慢指针找到链表的中心节点
  2. 反转链表的后半部分
  3. 判断链表是否回文
  4. 恢复链表后半部分
  5. 返回结果

代码

/**
 * 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;
};