链表OJ题(4)

简介: 链表OJ题(4)

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

🙂指针指向的前中后。

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

今天最后两道链表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;
        }
    };


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 作为传入参数。

示例一:

示例二:


【 尾插+某个位置插入】

  • 这道题目的综合性还挺强的,大家一定要把前面链表的知识扎根。才能轻易上手。
  • 单链表+随机链表(随机链表可以指向其他任何链表包括自己)
  • 不要一个指针搞定所有,大概率是会出错❌
  • 画图细致比较重要
/**
 * 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=copy->next;
   }
   //第二步
   cur=head;
   while(cur)
   {
       struct Node*copy=cur->next;
       if(cur->random == NULL)
       {
           copy->random=NULL;
       }
       else
       {
           copy->random=cur->random->next;//易错
       }
       cur=copy->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=copy;
       }
       else
       {
           tail->next=copy;
           tail=tail->next;
       }
       cur->next=copy->next;
       cur=copy->next;
   }
   //最后一个节点本来就指向NULL
   return newhead;
}


【找具体位置第几个】


但是这个方法的时间复杂度是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

联系---------→【邮箱:2784139418@qq.com】

目录
相关文章
|
1月前
【数据结构OJ题】环形链表
力扣题目——环形链表
26 3
【数据结构OJ题】环形链表
|
1月前
【数据结构OJ题】复制带随机指针的链表
力扣题目——复制带随机指针的链表
37 1
【数据结构OJ题】复制带随机指针的链表
|
1月前
【数据结构OJ题】环形链表II
力扣题目——环形链表II
14 1
【数据结构OJ题】环形链表II
|
1月前
【数据结构OJ题】相交链表
力扣题目——相交链表
18 1
【数据结构OJ题】相交链表
|
1月前
【数据结构OJ题】合并两个有序链表
力扣题目——合并两个有序链表
31 8
【数据结构OJ题】合并两个有序链表
|
1月前
【数据结构OJ题】移除链表元素
力扣题目——移除链表元素
31 2
【数据结构OJ题】移除链表元素
|
1月前
【数据结构OJ题】链表中倒数第k个结点
牛客题目——链表中倒数第k个结点
24 1
【数据结构OJ题】链表中倒数第k个结点
|
1月前
【数据结构OJ题】链表分割
牛客题目——链表分割
17 0
【数据结构OJ题】链表分割
|
1月前
【数据结构OJ题】链表的回文结构
牛客题目——链表的回文结构
22 0
【数据结构OJ题】链表的回文结构
|
1月前
【数据结构OJ题】链表的中间结点
力扣题目——链表的中间结点
17 0
【数据结构OJ题】链表的中间结点