链表OJ题(4)

目录

10.链表的回文结构

11.随机链表的复制


找中间节点一定要考虑偶数个和奇数个的问题。

指针指向的前中后。

链表节点的位置个数/链表的节点中的数字。

今天最后两道链表OJ题目。

10.链表的回文结构

描述

对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。

测试样例: 


 【快慢指针中间节点+逆置链表+比较链表】

  • 先找到链表的中间节点(分奇偶)
  • 逆置后半段链表
  • 两个指针比较两个链表
  • 结束条件,某个指正为NULL就结束
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:

    bool chkPalindrome(ListNode* A) {
        //找中间节点
        ListNode*slow=A;
        ListNode*fast=A;
        while(fast->next && fast)
        {
            fast=fast->next->next;
            slow=slow->next;
        }
        //逆置后半段链表
        ListNode*head=slow;
        ListNode*rhead=NULL;
        ListNode*cur=head;
        ListNode*tail=NULL;
        while(cur)
        {
            ListNode*tmp=cur->next;
            if(rhead == NULL)
            {
                rhead=tail=cur;
                rhead->next=NULL;
            }
            else 
            {
                rhead=cur;
                rhead->next=tail;
                tail=rhead;
            }
            cur=tmp;
        }
        //比较rhead
        while(rhead && A)
        {
            if(rhead->val != A->val)
            {
                return false;
            }
            rhead=rhead->next;
            A=A->next;
        }
        return true;
        }

    };

链表OJ题(4)_第1张图片


11.随机链表的复制(链表的深度拷贝)

给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。

构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 

例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。

返回复制链表的头节点。

用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

  • val:一个表示 Node.val 的整数。
  • random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  null 。

你的代码  接受原链表的头节点 head 作为传入参数。

示例一: 

链表OJ题(4)_第2张图片 

 示例二:

链表OJ题(4)_第3张图片


【 尾插+某个位置插入】

  • 这道题目的综合性还挺强的,大家一定要把前面链表的知识扎根。才能轻易上手。
  • 单链表+随机链表(随机链表可以指向其他任何链表包括自己)
/**
 * Definition for a Node.
 * struct Node {
 *     int val;
 *     struct Node *next;
 *     struct Node *random;
 * };
 */

struct Node* copyRandomList(struct Node* head) 
{
    //第一步
    struct Node*cur=head;
    while(cur)
    {
        struct Node*copy=(struct Node*)malloc(sizeof(struct Node));
        copy->val = cur->val;
        copy->next=cur->next;
        cur->next=copy;
        cur=cur->next->next;
    }
    //第二步
    cur=head;
    while(cur)
    {
        struct Node*copy=cur->next;
        if(cur->random == NULL)
        {
            copy->random=NULL;
        }
        else
        {
            copy->random=cur->random->next;
        }
        cur=cur->next->next;
    }
    //第三步
    cur=head;
    struct Node*newhead=NULL;
    struct Node*tail=NULL;
    while(cur)
    {
        struct Node*copy=cur->next;
        if(newhead == NULL)
        {
            newhead=tail=cur->next;
        }
        else
        {
            tail->next=cur->next;
            tail=tail->next;
        }
        cur->next=copy->next;
        cur=cur->next->next;
    }
    return newhead;
}//❌

链表OJ题(4)_第4张图片

链表OJ题(4)_第5张图片

链表OJ题(4)_第6张图片 


 【找具体位置第几个】

链表OJ题(4)_第7张图片

但是这个方法的时间复杂度是O(N^2),时间复杂度是非常高的,建议学会上面的方法。 

12.链表逆置(头插)和链表顺序(尾插) 

【头插】 

struct ListNode* reverseList(struct ListNode* head)
{
    struct ListNode*newhead=NULL;
    struct ListNode*cur=head;
    while(cur)
    {
        struct ListNode*tmp=cur->next;
        cur->next=newhead;
        newhead=cur;
        cur=tmp;
    }
    return newhead;
}

【尾插】

struct ListNode* removeElements(struct ListNode* head, int val) 
{
    struct ListNode* cur=head;
    struct ListNode* tail=NULL;
    struct ListNode* newhead=NULL;
    while(cur)
    {
        if(cur->val != val)
        {
            if(tail)
            {
                tail->next=cur;//易错
                tail=tail->next;
            }
            //处理头
            else
            {
                newhead=tail=cur;//易错
            }
            cur=cur->next;
        }
        else
        {
            struct ListNode* tmp=cur->next;
            free(cur);
            cur=tmp;
        }
    }
    //处理尾
    if(tail)
    {
        tail->next=NULL;
    }
    return newhead;
}

最近天气渐冷,大家要注意保暖哦。

代码---------→【唐棣棣 (TSQXG) - Gitee.com】

联系---------→【邮箱:[email protected]

你可能感兴趣的:(笔试题&练习题,链表,数据结构,c语言)