链表的回文结构

链表的回文结构

记录我第一次独立写出来一道困难题,技巧是慢慢积累出来的,我不是那种很聪明的人,但我一定不能做一个懒的人。
链表的回文结构
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。

我的大致思路是这样的:首先将这个链表A进行深拷贝一份,拷贝为链表B,然后将链表B进行翻转,然后A与B再进行逐个进行比较。

/*

struct ListNode {

    int val;

    struct ListNode *next;

    ListNode(int x) : val(x), next(NULL) {}

};*/

class PalindromeList {

  public:

    bool chkPalindrome(ListNode* A) {

        // write code here

        if (A == NULL)

            return false;

        if (A->next == NULL)

            return true;

        struct ListNode* pa = A;

        //将链表A深拷贝一份

        struct ListNode* B = deepCopy(A);

        //翻转

        B = reverseList(B);

        //翻转之后prev指向最后

        //逐步和A进行比较

        struct ListNode* pb = B;

        pa = A;

        while (pa) {

            if (pa->val != pb->val)

                return false;

            pa = pa->next;

            pb = pb->next;

        }

        return true;
        
    }

  public:

    //翻转链表

    struct ListNode* reverseList(struct ListNode* head) {

        struct ListNode* prev = NULL;

        struct ListNode* curr = head;

        while (curr) {

            struct ListNode* next = curr->next;

            curr->next = prev;

            prev = curr;

            curr = next;

        }

        return prev;

    }

    public:

    struct ListNode* deepCopy(struct ListNode* A)

{

    struct ListNode* pa = A;

    struct ListNode* B = (struct ListNode*)malloc(sizeof(struct ListNode));

    B->val = pa->val;

    B->next = NULL;

    pa = pa->next;

    struct ListNode* pb = B;

    while (pa)

    {

        struct ListNode* newnode = (struct ListNode*)malloc(sizeof(struct ListNode));

        newnode->val = pa->val;

        pb->next = newnode;

        pb = pb->next;

        pb->next = NULL;

        pa = pa->next;

    }

    return B;

}

};

链表的深拷贝

所谓深拷贝就是搞一个备份,这个备份和原来的结构相同,关系相同,是在同一个时间下另一个空间的存在。

struct ListNode* deepCopy(struct ListNode* A)

{

    struct ListNode* pa = A;

    struct ListNode* B = (struct ListNode*)malloc(sizeof(struct ListNode));

    B->val = pa->val;

    B->next = NULL;

    pa = pa->next;

    struct ListNode* pb = B;

    while (pa)

    {

        struct ListNode* newnode = (struct ListNode*)malloc(sizeof(struct ListNode));

        newnode->val = pa->val;

        pb->next = newnode;

        pb = pb->next;

        pb->next = NULL;

        pa = pa->next;

    }

    return B;

}

有关链表的深拷贝这个问题,leetcode上有相关的题目,以后如果再遇到了,我还会写在这里。
138.复制带随机指针的链表
![[Pasted image 20221108101753.png]]
这道题的难点在于怎么进行random指针的深拷贝,因为这个随机指针的指向毫无规律,所以由此我们就能想到让这个毫无规律变成有迹可循,我们首先在每一个节点后面先接上一个他们自身的拷贝,这样就可以在另一个空间上有一个复制体,但是只是这样还不够,我们发现,新节点的随机指针就应该指向旧结点随机指针指向的后一个结点,好了,随机指针的问题解决了,我们接下来要做的就是让新节点指向它的next的next这样新链表也就构建好了。

/**

 * Definition for a Node.

 * struct Node {

 *     int val;

 *     struct Node *next;

 *     struct Node *random;

 * };

 */

  

struct Node* copyRandomList(struct Node* head) {

    if (head == NULL) {

        return NULL;

    }

    struct Node* cur=head;

    while(cur)

    {

        struct Node* newnode=(struct Node*)malloc(sizeof(struct Node));

        newnode->val=cur->val;

        newnode->next=cur->next;

        cur->next=newnode;

        cur=newnode->next;

    }

    cur=head;

    while(cur)

    {

        if(cur->random==NULL)

        {

            cur->next->random=NULL;

            cur=cur->next->next;

        }

        else

        {

            cur->next->random=cur->random->next;

            cur=cur->next->next;

        }

    }

    cur=head->next;

    while(cur)

    {

        if(cur->next!=NULL)

        {

            cur->next=cur->next->next;

            cur=cur->next;

        }

        else

        {

            cur->next=NULL;

            cur=cur->next;

        }

    }

    return head->next;

}

链表的翻转

/**

 * Definition for singly-linked list.

 * struct ListNode {

 *     int val;

 *     struct ListNode *next;

 * };

 */

  
  

struct ListNode* reverseList(struct ListNode* head)

{

    struct ListNode* prev=NULL;

    struct ListNode* curr=head;

    while(curr)

    {

        struct ListNode* next=curr->next;

        curr->next=prev;

        prev=curr;

        curr=next;

    }

    return prev;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值