一起学习LeetCode热题100道(24/100)

24.回文链表(学习)

给你一个单链表的头节点 head ,请你判断该链表是否为
回文链表
。如果是,返回 true ;否则,返回 false 。

示例 1:

输入:head = 1,2,2,1

输出:true

示例 2:

输入:head = 1,2

输出:false

提示:

链表中节点数目在范围1, 105 内

0 <= Node.val <= 9

解析:
一、找到链表的中点

1.初始化两个指针 slow 和 fast,都指向链表的头节点 head。

2.进入循环,条件为 fast 和 fast.next 都不为 null(确保 fast 可以安全地移动两步)。

3.在循环内部,slow 指针每次向前移动一步(slow = slow.next),fast 指针每次向前移动两步(fast = fast.next.next)。

4.当循环结束时,slow 指针要么指向链表的中点(如果链表长度是偶数),要么指向中间两个节点的第一个(如果链表长度是奇数)。

二、反转链表的后半部分

1.从 slow 指针开始反转链表。注意,如果链表长度是奇数,我们实际上是从 slow.next 开始反转的,因为 slow 已经是指向中间节点的指针了。

2.使用三个指针 prev(初始化为 null),curr(初始化为 slow 或 slow.next,取决于链表长度是否为奇数),和 nextTemp 来反转链表。

3.在循环中,将 curr.next 保存到 nextTemp,然后将 curr.next 指向 prev,接着将 prev 向前移动到 curr,最后将 curr 向前移动到 nextTemp。

4.循环继续,直到 curr 为 null。此时,prev 就是反转后的链表的头节点。

三、比较前半部分和反转后的后半部分

1.初始化两个指针 p1 和 p2,分别指向原链表的头节点 head 和反转后的链表的头节点 prev。

2.进入循环,条件为 p2 不为 null(确保我们可以安全地遍历反转后的链表的后半部分)。

3.在循环内部,比较 p1.val 和 p2.val。如果它们不相等,则返回 false,因为链表不是回文的。

4.如果它们相等,则将 p1 和 p2 都向前移动一步(p1 = p1.next 和 p2 = p2.next)。

5.循环结束后,如果没有提前返回 false,则说明链表是回文的,返回 true。

javascript 复制代码
var isPalindrome = function(head) {
     if (!head || !head.next) return true;  
  
    let slow = head;  
    let fast = head;  
    let prevPtr = null;  
  
    // 使用快慢指针找到中点  
    while (fast && fast.next) {  
        prevPtr = slow;  
        slow = slow.next;  
        fast = fast.next.next;  
    }  
  
    // 如果链表长度为奇数,则跳过中点  
    if (fast) {  
        slow = slow.next;  
    }  
  
    // 反转链表的后半部分  
    let secondHalf = reverseList(slow);  
  
    // 比较前半部分和反转后的后半部分  
    let p1 = head;  
    let p2 = secondHalf;  
    while (p2) {  
        if (p1.val !== p2.val) {  
            return false;  
        }  
        p1 = p1.next;  
        p2 = p2.next;  
    }  
  
    // 如果需要,可以在这里恢复链表(可选)  
  
    return true; 
};

function reverseList(head) {  
    let prev = null;  
    let curr = head;  
    while (curr) {  
        let nextTemp = curr.next;  
        curr.next = prev;  
        prev = curr;  
        curr = nextTemp;  
    }  
    return prev; // 新的头节点  
}  
相关推荐
我是伪码农11 小时前
百蝶杯学习
学习
keyipatience12 小时前
JavaScript学习(1)书写位置,变量、数据类型、运算符
开发语言·前端·javascript·css·学习
hanlin0312 小时前
刷题笔记:力扣第32题-最长有效括号
笔记·算法·leetcode
All for pursuit.12 小时前
【动态规划-21】312.戳气球
数据结构·c++·算法·leetcode·动态规划
xian_wwq13 小时前
【学习笔记】Milvus 如何完成一次向量相似度检索,Milvus 索引到底应该怎么选?-15
笔记·学习·milvus
Hhuhkt14 小时前
3D 云养宠小游戏
学习
碧海银沙音频科技研究院15 小时前
基于炬芯ATS3089X自研AEC声学回声消除算法
算法
通问AI15 小时前
在两台 Mac Studio 上跑 800B 模型:MLX + RDMA over Thunderbolt 实测与四道门选型法
算法
ZywOo62315 小时前
《算法竞赛进阶指南》0x03 前缀和与差分
算法
Scintilla_y15 小时前
DAY2 滑动窗口
算法·leetcode·散列表