【力扣刷题实战】回文链表

大家好,我是小卡皮巴拉 

 文章目录

目录

力扣题目:回文链表

题目描述 

示例 1:

示例 2:

解题思路

问题理解

算法选择

具体思路

题目要点

完整代码(C语言)

兄弟们共勉 !!!  


每篇前言

博客主页:小卡皮巴拉

咱的口号:🌹小比特,大梦想🌹

作者请求:由于博主水平有限,难免会有错误和不准之处,我也非常渴望知道这些错误,恳请大佬们批评斧正。

力扣题目:回文链表

原题链接:回文链表

题目描述 

给定一个链表的 头节点 head ,请判断其是否为回文链表。

如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。

示例 1:

输入: head = [1,2,3,3,2,1]
输出: true

示例 2:

输入: head = [1,2]
输出: false

解题思路

问题理解

题目要求我们判断一个给定的链表是否为回文链表。回文链表意味着链表节点序列从前往后看和从后往前看是相同的。例如,链表 1->2->3->2->1 是回文的,而链表 1->2->3->4->5 不是。

算法选择

为了解决这个问题,我们可以采用以下步骤:

  1. 找到链表的中间节点:使用快慢指针法,快指针每次移动两步,慢指针每次移动一步,当快指针到达链表末尾时,慢指针正好在链表的中间。

  2. 反转链表的后半部分:从中间节点开始,反转链表的后半部分。

  3. 比较前半部分和反转后的后半部分:逐个节点比较前半部分和反转后的后半部分的节点值,如果所有节点值都相同,则链表是回文的。

具体思路

  1. 找到链表的中间节点

    • 使用快慢指针法,快指针 fast 每次移动两步,慢指针 slow 每次移动一步。

    • 当 fast 或 fast->next 为空时,slow 指向链表的中间节点。

  2. 反转链表的后半部分

    • 从中间节点开始,使用三指针法反转链表的后半部分。

    • 初始化三个指针 s1(新链表的头节点,初始为 NULL),s2(当前节点,初始为中间节点),s3(下一个节点,初始为 s2->next)。

    • 在循环中,将 s2->next 指向 s1,然后移动指针:s1 指向 s2s2 指向 s3s3 指向 s3->next

    • 当 s2 为空时,反转完成,s1 是反转后的链表头节点。

  3. 比较前半部分和反转后的后半部分

    • 初始化两个指针 left 和 right,分别指向链表的前半部分和反转后的后半部分的头节点。

    • 在循环中,逐个比较 left 和 right 节点的值,如果不相等,则返回 false

    • 移动指针 left 和 right,直到 right 为空。

    • 如果所有节点值都相等,则返回 true

题目要点

  • 快慢指针法:用于找到链表的中间节点。

  • 三指针法反转链表:用于反转链表的后半部分。

  • 节点值比较:用于判断链表是否为回文。

完整代码(C语言)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode ListNode;
//找中间结点
ListNode* middleNode(ListNode* head)
{
    //快慢指针找到中间结点
    ListNode* slow = head;
    ListNode* fast = head;
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}
//反转链表
ListNode* reverseList(ListNode* head)
{
    if(head == NULL)
    {
        return head;
    }
    //三指针法反转后半段链表
    ListNode* s1 = NULL,* s2 = head,*s3 = head->next;
    while(s2)
    {
        s2->next = s1;
        s1 = s2;
        s2 = s3;
        if(s3)
           s3 = s3->next;
    }
    return s1;
}
bool isPalindrome(struct ListNode* head)
{
    //思路:1.找中间结点 2.反转以中间结点为头的后半段链表
    //3.遍历比较前半段链表和后半段链表,若完全相同则回文

    //找中间结点
    ListNode* mid = middleNode(head);
    //反转以中间结点为头的后半段链表
    ListNode* right = reverseList(mid);
    //左半段链表
    ListNode* left = head;
    //遍历比较前半段链表和后半段链表
    while(right)
    {
        if(left->val != right->val)
        {
            return false;
        }
        left = left->next;
        right = right->next;
    }
    return true;
}

兄弟们共勉 !!!  

码字不易,求个三连

抱拳了兄弟们!

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值