LeetCode热题(JS版) - 234. 回文链表

97 阅读1分钟

题目描述

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

示例 1:

输入: 1->2
输出: false

示例 2:

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

进阶:

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

解法思路

本题可以使用双指针算法来解决,先找到链表中点位置,然后将中点之后的链表进行翻转,最后将翻转后的链表与原链表进行对比即可。

具体做法如下:

  • 定义快指针 fast 和慢指针 slow,让它们分别指向链表的头结点。
  • 使用快慢指针找到链表的中点位置,即当快指针到达链表末尾时,慢指针恰好走到了链表中点位置。
  • 将链表中点位置之后的部分进行翻转。
  • 同时遍历翻转后的链表和原链表,如果两个链表的值不相等,则说明该链表不是回文链表,返回 false;否则继续遍历,直到遍历完成,返回 true

代码实现

function isPalindrome(head: ListNode | null): boolean {
  if (head === null) {
    return true;
  }

  let slow = head;
  let fast = head;

  while (fast && fast.next) {
    slow = slow.next;
    fast = fast.next.next;
  }
  // 初始化:reverse -> null;slow -> next
  let reverse = null;
  while (slow !== null) {
    let temp = slow.next;// 取出下个节点,便于继续遍历
    
    // 翻转:slow -> next 变成 reverse <- slow
    slow.next = reverse;
    
    // 后移:头节点,slow节点后移
    reverse = slow;
    slow = temp;
  }

  while (reverse !== null && head !== null) {
    if (reverse.val !== head.val) {
      return false;
    }
    reverse = reverse.next;
    head = head.next;
  }

  return true;
};

image.png

复杂度分析

  • 时间复杂度为 O(n),其中 n 是链表的长度。找到链表中点位置需要遍历一次,翻转后半部分链表需要遍历一次,对比两个链表需要遍历一次。

  • 空间复杂度为 O(1),因为只使用了常数级别的额外空间。