【牛客网】链表的回文结构

【牛客网】链表的回文结构_第1张图片

思路1:找到中间节点,从中间节点向后反转链表

寻找链表的中间节点和反转链表的程序已经讲解过

寻找链表的中间节点:CSDN

反转链表:CSDN

然后从头节点和中间节点依次向后比较节点的值

Note:

后半段链表反转后,需要更新mid的值

需要分奇数个节点的链表和偶数个节点的链表比较

1️⃣奇数个节点的链表

【牛客网】链表的回文结构_第2张图片

Note:

对于奇数个节点的链表,比较结束的条件是mid->next == NULL

2️⃣偶数个节点的链表

【牛客网】链表的回文结构_第3张图片Note:

对于偶数个节点的链表,比较结束的条件是mid == NULL

参考代码如下:

bool chkPalindrome(ListNode* A) {
    // write code here
    //寻找中间节点 
    struct ListNode* slow = A;
    struct ListNode* fast = A;
    struct ListNode* head = A;

    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    struct ListNode* mid = slow;

    //反转后半段
    //struct ListNode* midhead = mid;
    struct ListNode* n1 = NULL;
    struct ListNode* n2 = mid;
    struct ListNode* n3 = NULL;

    while (n2)
    {
        n3 = n2->next;
        n2->next = n1;

        n1 = n2;
        n2 = n3;
    }
    //反转之后,n2指向空,n1指向新的头
    mid = n1;

    //比较
    while (mid && mid->next)
    {
        if (head->val == mid->val)
        {
            head = head->next;
            mid = mid->next;
        }
        else
        {
            return false;
        }
    }

    return true;

}

思路二:反转整个链表,从头结点开始与原链表依次比较

【牛客网】链表的回文结构_第4张图片

由上图:回文结构的链表反转后与原链表相同,非回文结构的链表反转后与原链表不同

参考代码如下:

bool chkPalindrome(ListNode* A) 
{
    //反转整个链表再比较
    struct ListNode* newhead = NULL;
    struct ListNode* n1 = NULL;
    struct ListNode* n2 = A;
    struct ListNode* n3 = NULL;

    while (n2)
    {
        n3 = n2->next;
        n2->next = n1;

        n1 = n2;
        n2 = n3;
    }
    newhead = n1;

    //比较
    struct ListNode* head = A;
    while (head)
    {
        if (head->val == newhead->val)
        {
            head = head->next;
            newhead = newhead->next;
        }
        else
        {
            return false;
        }
    }

    return true;

}

你可能感兴趣的:(实例,链表,数据结构,算法)