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

链表的回文结构

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) {
//         int arr[900]={0};
//         ListNode *pcur=A;
//         int i=0;
//         while(pcur)//遍历原链表,pcur不能为空
//         {
//             //将链表中每个节点的值放到arr中
//             arr[i]=pcur->val;
//             i++;
//             pcur=pcur->next;//换下一个节点
//         }
//         //i即节点的个数,因为我们的i一直在进行++操作

//         //找中间节点,判断是否为回文数字
//         int left=0;
//         int right=i-1;//i是数组中数据的有效个数
//         //我们比较left和right的下标的数字的大小,相等的话我们就让两个指针一直走,直到遍历整个数组
//         while(left<right)
//         {
//             if(arr[left]!=arr[right])
//             {
//                 //那么肯定不是回文结构
//                 return false;
//             }
//             right--;
//             left++;

//         }
//         //说明是回文结构,因为已经跳出循环了
//         return true;
//     }
// };


//这道题我们注意:我们开辟了空间,arr[900]
//但是假如我们碰到的题没有对链表节点个数进行限制的话,那么这种思路的话肯定是不行的

//除此之外,该思路只能在牛客上通过,力扣是不行的




//思路二:反转链表
/*
1.找链表的中间节点(快慢指针) 
2.将中间节点及中间节点之后的链表进行反转
此时我们的right和left就能接着后面进行比较了
*/
/*反转链表的思路:
创建三个指针,n1 n2 n3
解释下思路二:
 一开始我们的n1是空指针,n2指向的是1,n3指向的是2
 我们将n2的指向改变指向n1,然后1就指向了空指针1->NULL

 然后我们将n1放到n2的位置,n2放到n3的位置,那么现在n1指向的是1,n2指向的是2,n3指向的是3
 我们将n2的指向改变指向为n1   2->1->NULL

 然后我们将n1放到n2的位置,n2放到n3的位置,那么现在n1指向的是2,n2指向的是3,n3指向的是4 我们将n2的指向改变指向为n1     3->2->1->NULL

然后我们将n1放到n2的位置,n2放到n3的位置,那么现在n1指向的是3,n2指向的是4,n3指向的是5 我们将n2的指向改变指向为n1     4->3->2->1->NULL

然后我们将n1放到n2的位置,n2放到n3的位置,那么现在n1指向的是4,n2指向的是5,n3指向的是走出去了 我们将n2的指向改变指向为n1     5->4->3->2->1->NULL

最后n1走到n2,n2走到n3    n2和n3都走出去了,现在的n1指向的是5的位置,那么现在的5就是新的头结点了


*/

class PalindromeList
{
public:
    ListNode*findMidNode(ListNode* phead)//封装一个函数来找中间节点
    {
        //快慢指针
        ListNode*slow=phead;
        ListNode*fast=phead;
        while(fast&&fast->next)//fast和fast下个节点不为空
        {
            slow=slow->next;//慢指针每次走一步
            fast=fast->next->next;//快指针每次走两次
        }
        //那么此时的slow节点刚好指向了中间节点
        return slow;

    }
    ListNode*reverseList(ListNode* phead)//封装一个函数来反转链表
    {
        ListNode*n1,*n2,*n3;
        n1=NULL;
        n2=phead;
        n3=n2->next;
        while(n2)//当n2为空的时候,那么此时的n1就指向的是反转后链表的头
        {
            n2->next=n1;
            n1=n2;
            n2=n3;
            if(n3)//n3不能为空才能往下走,只要n3到空了,我们就没必要让n3继续走了
            {
                n3=n3->next;
            }
        }
        //跳出循环 此时的n1就是反转后链表的头节点
        return n1;
    }
    bool chkPalindrome(ListNode* A)
    {
        //1.找中间节点
        ListNode*mid=findMidNode(A);//将链表A传过去


        //2.根据中间节点反转后面的链表
        ListNode*right=reverseList(mid);//将mid传过去,作为后半段头结点
        //那么此时的right就是指向的是反转后链表的头结点

        
        //3.从原链表和反转链表比较节点的值
        ListNode*left=A;//让left赋值为头节点
        //让right和left对应的指针进行一一比较
        while(right)//我们以right为主,一但right遍历到空,我们就没必要进行比较了
        {
            if(left->val!=right->val)//那么就不是回文结构了
            {
                return false;
            }
            //走到这里就说明当前节点对应的大小是相等的,那么我们就进行下一对节点的比较
            //让两个指针往后走
            left=left->next;
            right=right->next;
        }
        //跳出循环,那么此时的right已经为空了
        //那么这个链表的结构就是回文结构了
        return true;
    }




};




全部评论

相关推荐

牛客868257804号:九个中铁八个中建
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务