题解 | #链表的回文结构#

链表的回文结构

https://www.nowcoder.com/practice/d281619e4b3e4a60a2cc66ea32855bfa

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:
    bool chkPalindrome(ListNode* A)
    {
        //特殊情况的操作
        if(A==NULL||A->next==NULL)//如果是空链表或者是一个节点的链表的话,那么肯定是回文结构的
        {
            return true;
        }

        //使用快慢指针找到链表的中间节点,最后停下来的时候慢指针就在中间节点上面
        ListNode *slow=A;
        ListNode *fast=A;
        while(fast!=NULL&&fast->next!=NULL)
        {
            slow=slow->next;//慢指针移动一步
            fast=fast->next->next;//快指针移动两步
        }

        //2.反转链表的后半部分
        ListNode *prev=NULL;
        ListNode *cur=slow;//这个时候的slow在这个链表的中间节点,那么我们从中间节点反转后半部分
        while(cur!=NULL)//从当前位置进行遍历后半部分的链表
        {
            //下面就是链表反装的代码,将后半部分链表进行反装的操作
            ListNode *nexttmp=cur->next;//保存当前节点的下个节点

            //下面两个代码是当前节点和前一个节点的转换操作
            //当前节点的next指向我们的前一个节点
            cur->next=prev;//将当前节点的指针反装,指向前一个节点,
            prev=cur;//当前的节点变成了上一个节点了

            cur=nexttmp;//更换当前的节点继续进行转换的操作,将后面剩下的节点进行转换操作
        }

        //这个时候我们的prev就变成了我们反转后连标记的头结点了
        //3.接下来我们比较链表二档前半部分和反转后的后半部分
        ListNode *firstHalf=A;//前半部分从链表头开始
        ListNode* secondHalf = prev;//后半部分从反转链表的头结点开始
        while(secondHalf != NULL)//比较每个节点,直到我们的反转链表部分遇到了空
        {
            if(firstHalf->val!=secondHalf->val)
            {
                return false;//如果两个节点的值对应不上的话,那么我们就可以判断这个链表不是回文的
            }
            //比较完成之后指针就往后移动了
            firstHalf=firstHalf->next;
            secondHalf = secondHalf->next;
        }
        //运行到这里,就说明我们的链表是回文的了,那么我们直接返回结果就行了
        return true;
        
    }
};

全部评论

相关推荐

joe2333:怀念以前大家拿华为当保底的日子
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务