leetcode234--回文链表

本文介绍两种高效判断链表是否为回文结构的方法。方法一通过将链表元素转化为列表并检查列表是否回文;方法二使用快慢指针定位链表中点,反转后半部分链表,然后对比前后两部分。方法二更为高效,仅需1ms,占用42.5MB内存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

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

示例 1:

输入: 1->2
输出: false
示例 2:

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

方法一

上来做这道题,最先想到的方法就是建一个列表,遍历一遍链表,将每一个值存入列表,然后再对列表进行循环判断是否回文。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head==null) return true;
        List<Integer> list = new ArrayList<Integer>();
        while(head!=null){
            list.add(head.val);
            head = head.next;

        }
        
        int count=list.size()-1;
        for(int i=0;i<list.size();i++){
        	//此处不能用==判断相等
            if(!list.get(i).equals(list.get(count))){
                return false;
            }
            count--;

        }
        return true;

    }
}

在算法中有一个需要注意的点,不能用==判断相等,必须用equals否则报错。如在输入为[128,128]时报错。查了查资料,才知道是因为:JVM会自动维护八种基本类型的常量池,int常量池中初始化-128~127的范围,所以当为Integer i=127时,在自动装箱过程中是取自常量池中的数值,而当Integer i=128时,128不在常量池范围内,所以在自动装箱过程中需new 128,所以地址不一样。
用时:5ms,内存:43.6MB。

方法二

看了一些其他解法,有了下边的代码

class Solution {
    public boolean isPalindrome(ListNode head) {
        //solution2
        if(head==null || head.next ==null) return true;
        ListNode fast = head;
        ListNode slow = head;
        ListNode pre = null;
        //快慢指针,找到链表的中点
        while(fast!=null && fast.next!=null){
            slow = slow.next;
            fast = fast.next.next;
        }
        //将slow之后的链表反转
        while(slow!=null){
            ListNode next = slow.next;
            slow.next = pre;
            pre = slow;
            slow = next;
        }
        //前后链表进行比较,若为奇数链表,多一个节点,也不影响判断回文
        while(head!=null && pre!=null){
            if(head.val!=pre.val) return false;
            head = head.next;
            pre = pre.next;
        }
        return true;
    }
}

用时:1ms,内存:42.5MB。