力扣Hot100——234.回文链表

234.回文链表

解题思路

回文链表的话,就是第一个数和倒数第一个数相同,第二个数和倒数第二个数相同,一次类推,但是链表我们无法直接从最后一个节点开始从后往前推,因此对于判断是不是回文链表,首先我们需要找到链表的中间节点

1. 链表的中间节点

对于长度为奇数 的链表,正中间的节点就是中间节点。

对于长度为偶数 的链表,找正中间右边的节点。

举例如下:

对于链表

1->2->3->4->5

中间节点就是正中间的3。

对于链表

1->2->3->4->5->6

中间节点是正中间右边的4。

2.反转链表

随后对得到了中间节点之后的链表部分进行反转链表,也就是说:

奇数链表:

3->4->5反转为3<-4<-5,而另一边1->2->3

偶数链表

1->2->3->4,而另一边4<-5<-6。

3.回文链表判断

我们记反转后的头节点是head2。

同时得注意得到了反转之后的链表之后,进行回文判断的时候,判断条件当中应该是head2是否为空,如果判断条件当中是head的话,那么对于奇数情况,head要比head2多走一步,但这时候head2已经是空的了,就会出现问题(head2.val,空指针异常)。

如何得到链表的中间节点呢?

使用快慢指针法,让快慢指针同时指向head,快指针每次移动2步,慢指针每次移动1步,当快指针为null或者快指针的next为null时,此时满指针的所指就是中间节点。

代码

C++

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    //找到中间节点
    ListNode* Getmidddle(ListNode* head)
    {
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast && fast->next)
        {
            slow = slow->next;
            fast = fast->next->next;
        } 
        return slow;
    }

    //反转中间节点之后的链表部分
    ListNode* ReverseLink(ListNode* head)
    {
        ListNode* pre = NULL;
        ListNode* cur = head;
        ListNode* nxt = NULL;
        while(cur)
        {
            nxt = cur->next;
            cur->next = pre;
            pre = cur;
            cur = nxt;
        }
        return pre;
    }
    bool isPalindrome(ListNode* head) {
        //得到中间节点
        ListNode* middle = Getmidddle(head);
        ListNode* head2 = ReverseLink(middle);
        while(head2)
        {
            if(head->val != head2->val)
                return false;
            head = head->next;
            head2 = head2->next;
        }
        return true;
    }
};

python

python 复制代码
# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):

    # 找到中间结果,对于奇数,直接就是中间
    # 对于偶数,则是中间的右边节点
    def GetMiddleNode(self, head):
        """
        :type head: Optional[ListNode]
        :rtype: ListNode
        """
        slow, fast = head, head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
        return slow

    # 反转链表
    # 反转从中间节点到原本链表之间的关系,比如1->2->3->4->5->6
    # 反转后:1->2->3->4<-5<-6
    def reverseLink(self, head):
        """
        :type head: Optional[ListNode]
        :rtype: ListNode
        """
        pre, cur= None, head
        while cur:
            nxt = cur.next
            cur.next = pre
            pre = cur
            cur = nxt
        return pre
        

    def isPalindrome(self, head):
        """
        :type head: Optional[ListNode]
        :rtype: bool
        """
        #1. 找到中间节点
        middle = self.GetMiddleNode(head)
        #2. 反转链表
        head2 = self.reverseLink(middle)
        while head2:
            if head.val == head2.val:
                head = head.next
                head2 = head2.next
            else:
                return False
        return True
            


        

参考

O(1) 空间做法:寻找中间节点+反转链表(Python/Java/C++/C/Go/JS/Rust)

相关推荐
自信150413057592 小时前
数据结构之实现链式结构二叉树
c语言·数据结构·算法
Barkamin2 小时前
堆排序简单实现
java·数据结构·算法·排序算法
迈巴赫车主2 小时前
天梯赛 L2-004 这是二叉搜索树吗?java
java·开发语言·数据结构·算法·天梯赛
沐苏瑶2 小时前
Java 数据结构精讲:二叉树遍历算法与底层实现剖析
数据结构·算法
董董灿是个攻城狮3 小时前
大模型连载8:词向量如何表示近义词?
人工智能·python·算法·机器学习
Jasmine_llq3 小时前
《B4001 [GESP202406 一级] 立方数》
算法·单输入处理·整数算术运算·立方数枚举验证算法(核心逻辑)·循环终止优化算法·状态标记算法·三元运算符输出
芸忻3 小时前
day 13 第六章 二叉树 part01代码随想录算法训练营71期
数据结构·算法
2401_900151543 小时前
C++中的桥接模式
开发语言·c++·算法
小O的算法实验室3 小时前
2026年IEEE TNSE SCI2区,基于预测的双阶段分布式任务分配方法+搜救场景中最大化任务分配,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进