面试题 02.06. 回文链表 C语言实现

题目描述:

编写一个函数,检查输入的链表是否是回文的。

原题链接

解题思路:

本人的思路是,首先找到链表的中间结点的前一个结点,如果链表是偶数个,则直接分开成两个链表,然后将前一个链表逆置再依次判断结点的大小是否相等。如果链表结点是奇数个,直接将中间结点删去,该就变成 为偶数个,按照上面的方法继续求解。

代码:

// 该方法找的不是中间值,而是中间值的前一个,如果是偶数则返回前一个中间值
//如果是奇数,则删掉中间值并返回前一个值
struct ListNode* getMid(struct ListNode* head)
{
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    struct ListNode* pre = slow;
    while(fast && fast->next)
    {
        pre = slow;
        slow = slow->next;
        fast = fast->next->next;
        if(fast!=NULL && fast->next==NULL)
        {
            pre->next = slow->next;
        }
    }
    return pre;
}
bool isPalindrome(struct ListNode* head){
    if(head==NULL)
    {
        return true;
    }
    // 获取前一个链表的尾结点
    struct ListNode* mid = getMid(head);
    // 获取后一个链表的头结点
    struct ListNode* behind = mid->next;
    //将前一个链表的尾结点置空
    mid->next = NULL;
    struct ListNode* pre = NULL;
    struct ListNode* p_next;
    while(head!=NULL)
    {
        p_next = head->next;
        head->next = pre;
        pre = head;
        head = p_next;
    }
    while(pre && behind)
    {
        if(pre->val==behind->val)
        {
            pre = pre->next;
            behind = behind->next;
        }
        else
        {
            return false;
        }
    }
    return true;
}

然而看了解析发现,无需判断链表是否为偶数还是奇数,且无需把分开后的前一个链表的最后链接置为空。后一个链表的头结点是链表的中间结点 mid,且此解不是将前一个链表逆置,而是将后一个链表逆置,逆置后前一个链表的最后一个结点指向的是后一个链表的最后一个结点,这样链表无论是偶数个元素还是奇数个,如果是回文链表,每一个元素的值都还是相同的。

代码

// 获取中间值,如果是偶数返回第二个中间值
struct ListNode* getMid(struct ListNode* head)
{
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}
// 逆置函数
struct ListNode* reverse(struct ListNode* head)
{
    struct ListNode* newHead = NULL;
    while(head)
    {
        struct ListNode* h_next = head->next;
        head->next = newHead;
        newHead = head;
        head = h_next;
    }
    return newHead;
}
bool isPalindrome(struct ListNode* head){
    if(head==NULL)
    {
        return true;
    }
    struct ListNode* mid = getMid(head);
    struct ListNode* behind = reverse(mid);
    while(behind)
    {
        if(head->val==behind->val)
        {
            head = head->next;
            behind = behind->next;
        }
        else
        {
            return false;
        }
    }
    return true;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值