leetcode 234. Palindrome Linked List(Easy) 回文链表

这篇博客探讨了如何在给定的链表中判断其是否为回文,重点在于在O(n)的时间复杂度和O(1)的空间复杂度下实现。通过使用快慢指针找到链表中点,然后反转后半部分链表,并与前半部分进行比较,从而确定链表的回文性质。代码实现中详细展示了这个过程,包括反转链表的辅助函数。最后,分析了算法的时间和空间复杂度。

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

1. Description

Given the head of a singly linked list, return true if it is a palindrome.
Follow up: Could you do it in O(n) time and O(1) space?
请判断一个链表是否为回文链表。

2. Analysis

  • 链表不好判断回文的原因是链表指针的单向性,无法获得前驱结点。故本题第一反应将链表整个反转后与原链表进行比较,但此方法产生了一条与原链表长度相等的新链表,不满足O(1)空间复杂度。
  • 既然不能产生大小为n的新的存储空间,能否直接在原链表上进行反转操作后进行回文判断?答案是肯定的,我们只需要反转链表的后半部分,再比较链表的前半部分和后半部分即可
  • 要想反转后半部分,需要使用快慢指针找到中间节点,反转操作和比较操作较为简单,这里不加赘述。
  • 快慢指针:

3. Code

class Solution{
    public boolean isPalindrome(ListNode head){
        // 快慢指针找到链表中点
        ListNode fast, slow;
        fast = slow = head;
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        // 奇数情况slow再移一步
        if(fast != null) slow = slow.next;
        // 反转从slow开始的链表
        ListNode right = reverse(slow);
        ListNode left = head;
        // 对两段链表进行比较
        while(right != null){
            if(left.val != right.val) return false;
            left = left.next;
            right = right.next;
        }
        return true;
    }
    /*
    	反转以head为头节点的链表并返回新链表的头节点
    */
    private ListNode reverse(ListNode head){
       ListNode prev = null, cur = head;
       ListNode nxt = head;
       while(cur != null){
           nxt = cur.next;
           cur.next = prev;
           prev = cur;
           cur = nxt;
       }
       return prev;
    }
}

4. Complexity

  • Time:未出现循环的嵌套,出现了对链表的遍历,O(n)
  • Space:未开辟链表长度大小的存储空间,只使用了常数个变量,O(1)

5. Summary

  • 本题核心在于找到中间节点(快慢指针),反转后半部分,比较前半部分和反转后的后半部分
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值