判断链表是否为回文

所谓回文,就是从前往后读和从后往前读都一样,比如 1→2→3→2→1 就是回文链表。

代码逻辑

1.找到链表的中点

java 复制代码
ListNode slow = head, fast = head;
while (fast.next != null && fast.next.next != null) {
    slow = slow.next;
    fast = fast.next.next;
}

这里判断条件是 fast.next != null && fast.next.next != null,能保证 slow 最终停在中间偏左的位置,无论链表长度是奇数还是偶数都适用。

2.翻转后半部分链表

从中点开始,把后半部分链表反转。

反转后,链表变成了一个"双向箭头"的结构:前半部分从 head 指向中点,后半部分从尾部指向中点。

java 复制代码
ListNode pre = slow;
ListNode cur = pre.next;
ListNode next = null;
pre.next = null;  // 断开前后两部分

while (cur != null) {
    next = cur.next;      // 保存下一个节点
    cur.next = pre;       // 反转指针
    pre = cur;            // pre 前进
    cur = next;           // cur 前进
}

3.双指针比对值

现在有两个指针:left 从头开始往右走,right 从尾开始往左走。

每一步比对两个节点的值,如果不相等就说明不是回文。

java 复制代码
boolean ans = true;
ListNode left = head;
ListNode right = pre;

while (left != null && right != null) {
    if (left.val != right.val) {
        ans = false;
        break;
    }
    left = left.next;
    right = right.next;
}

4.恢复链表原状

判断完成后,不能把链表留成反转的状态,需要把后半部分再翻转回去。

java 复制代码
cur = pre.next;
pre.next = null;
while (cur != null) {
    next = cur.next;
    cur.next = pre;
    pre = cur;
    cur = next;
}

完整代码

java 复制代码
public static boolean isPalindrome(ListNode head) {
    if (head == null || head.next == null) {
        return true;
    }
    
    ListNode slow = head, fast = head;
    // 找中点
    while (fast.next != null && fast.next.next != null) {
        slow = slow.next;
        fast = fast.next.next;
    }
    
    // 翻转后半部分
    ListNode pre = slow;
    ListNode cur = pre.next;
    ListNode next = null;
    pre.next = null;
    while (cur != null) {
        next = cur.next;
        cur.next = pre;
        pre = cur;
        cur = next;
    }
    
    // 双指针比对
    boolean ans = true;
    ListNode left = head;
    ListNode right = pre;
    while (left != null && right != null) {
        if (left.val != right.val) {
            ans = false;
            break;
        }
        left = left.next;
        right = right.next;
    }
    
    // 恢复链表
    cur = pre.next;
    pre.next = null;
    while (cur != null) {
        next = cur.next;
        cur.next = pre;
        pre = cur;
        cur = next;
    }
    
    return ans;
}
相关推荐
inrichtt7 小时前
第八课时:SPI总线揭秘:四线全双工通信的奥
c语言·数据结构·stm32·单片机·嵌入式硬件
HPtiger8 小时前
数据结构——选择排序
数据结构·算法·排序算法
丑梨数据8 小时前
信创环境里跑文档工具:格式兼容与本地合规的几个坑
数据结构·人工智能·算法·决策树·排序算法
烂蜻蜓9 小时前
Pandas入门教程(四):Series数据结构——创建、索引与常用方法
数据结构·pandas
CS创新实验室16 小时前
一棵树怎么做到“自平衡还不太费力“?——红黑树的旋转与染色
数据结构·算法·红黑树·408·计算机考研
Logic10116 小时前
C语言/数据结构位运算题解:异或XOR找出被挑选一次的果子编号——只出现一次的数字
c语言·数据结构·算法·数组·位运算·时间复杂度·空间复杂度
从小白到软工18 小时前
4-3 项目-学生成绩管理系统(上)
c语言·开发语言·数据结构·经验分享·ai编程
悠仁さん18 小时前
非类型模板参数的特化与偏特化
java·数据结构·算法
haluhalu.18 小时前
深入理解 AI Agent(1.2):Harness 工程——模型之外的竞争力
前端·数据结构·人工智能·python·langchain·个人开发
垆边人似月.19 小时前
幻兽防御战(贪心算法)
数据结构·算法