首页IT科技leetcode删除链表中的节点(【Leetcode】移除链表元素 链表的中间节点 链表中倒数第k个节点)

leetcode删除链表中的节点(【Leetcode】移除链表元素 链表的中间节点 链表中倒数第k个节点)

时间2025-04-30 05:53:44分类IT科技浏览3775
导读:目录...

目录

一.【Leetcode203】移除链表元素

1.链接

2.题目再现

 A.双指针法

B.类尾删法

C.哨兵位

二.【Leetcode876】链表的中间节点

1.链接:链表的中间节点

2.题目再现

3.解法:快慢指针

三.链表中倒数第k个节点

1.链接:链表中倒数第k个节点

2.题目再现

3.解法 :快慢指针

一.【Leetcode203】移除链表元素

1.链接

移除链表元素

2.题目再现

 A.双指针法

1.创建一个指针 cur=head  和一个指针  pre=NULL;  

2.用cur->val 与 val 比较,如果不相等则把 cur 赋给 pre 使cur 指向下一个节点        ,即

   cur=cur->next

3.如果相等则使 pre 的 next 指向 cur 的 next                 ,即:

 pre->next=cur->next      ,然后再 free 掉 cur ,最后再使 cur 等于 pre 的 next      ,注意在进行这些步骤之前要判断 pre 是否为空                ,若为空即为头删;

演示:

代码:

struct ListNode* removeElements(struct ListNode* head, int val) { struct ListNode*pre=NULL; struct ListNode*cur=head; while(cur) { if(cur->val!=val) { pre=cur; cur=cur->next; } else { if(pre==NULL) { head=cur->next; free(cur); cur=head; } else { pre->next=cur->next; cur=pre->next; } } } return head; }

B.类尾删法

1.创建一个新的指针newhead          ,同时为了省去找尾的麻烦    ,我们可以定义一个尾指针 tail 来保存尾节点;

2.再创建一个指针 cur =head ,用来遍历链表;

3.如果 cur->val != val               ,则尾插             ,注意要判断 tail 是否为空   ,类似于单链表的尾插那部分             ,如果不理解的话               ,可查看文章 :单链表的增删查改;

4.如果 cur->val ==val,则 cur=cur->next ;

5.最后要将尾节点置空        。

演示:

类尾插

代码:

struct ListNode* removeElements(struct ListNode* head, int val) { struct ListNode *newhead=NULL; struct ListNode*tail=NULL; struct ListNode*cur=head; while(cur) { if(cur->val!=val) { if(tail==NULL) { newhead=tail=cur; } else { tail->next=cur; tail=tail->next; } cur=cur->next; } else { cur=cur->next; } } if(tail) { tail->next=NULL; } return newhead; }

C.哨兵位

1.malloc 一个哨兵位节点 dummyhead          ,使其 next 指向 head ;

2.再定义一个节点 tmp = dummyhead                  ,用这个遍历链表;

3.注意因为 tmp ->next 才是 head   ,所以 while 里要写 tmp->next !=NULL

演示:

移除链表元素 哨兵位法动态演示

代码:

struct ListNode* removeElements(struct ListNode* head, int val) { struct ListNode*dummyhead=(struct ListNode*)malloc(sizeof(struct ListNode)); dummyhead->next=head; struct ListNode*tmp=dummyhead; while(tmp->next!=NULL) { if(tmp->next->val==val) { tmp->next=tmp->next->next; } else { tmp=tmp->next; } } return dummyhead->next; }

二.【Leetcode876】链表的中间节点

1.链接:链表的中间节点

2.题目再现

3.解法:快慢指针

1.定义一个快指针 fast 和一个慢指针 slow 都初始化为 head;

2.遍历链表        ,快指针一次走2步                ,慢指针一次走1步 ;

3.注意:因为链表的长度可能是单数也可能是双数      ,所以当我们已 fast 是否为NULL 作为循环控制条件的话      ,要在 fast 走2步前判断 fast->next 是否为空

4.最后慢指针就是中间节点                。

演示:

链表中间节点 快慢指针动态演示

代码:

struct ListNode* middleNode(struct ListNode* head) { struct ListNode*slow=head; struct ListNode*fast=head; while(fast) { if(fast->next==NULL) //注意判断 { break; } else { fast=fast->next->next; //fast 走2步 } slow=slow->next; //slow 走1步 } return slow; //返回慢指针 }

三.链表中倒数第k个节点

1.链接:链表中倒数第k个节点

2.题目再现

3.解法 :快慢指针

1.定义一个快指针 fast 和一个慢指针 slow 都初始化为 head;

2.因为倒数第k个节点和尾节点的差为 k-1                 ,所以我们先让快指针先走 k-1 步;

或者因为尾节点所指向的NULL 和倒数第k个节点相差k         ,也可以先让快指针走k步;

这个时候慢指针不动;

3.快指针走完后    ,快指针和慢指针依次走              ,每次只走1步

注意            ,如果是k-1  ,那么遍历结束的条件是fast->next 是否为空              ,如果是k               ,那么遍历结束的条件是fast 是否为空;

4.返回慢指针      。

演示:

链表倒数第K个节点 快慢指针动态演示

代码:

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) { if(pListHead==NULL) { return NULL; } struct ListNode*slow=pListHead; struct ListNode*fast=pListHead; while(k--) //这里以先走k步为例 { if(fast==NULL) { return NULL; } fast=fast->next; } while(fast) { slow=slow->next; fast=fast->next; } return slow; }

😽本篇文章到此就结束了,若有错误或是建议          ,欢迎小伙伴们指出;😻

😍请多多支持博主哦~🥰

🤩谢谢你的阅读~😃

声明:本站所有文章                 ,如无特殊说明或标注   ,均为本站原创发布      。任何个人或组织        ,在未征得本站同意时                ,禁止复制            、盗用              、采集    、发布本站内容到任何网站         、书籍等各类媒体平台               。如若本站内容侵犯了原著者的合法权益      ,可联系我们进行处理         。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
服务器证书不可用怎么办(服务器安装ssl证书错误怎么回事) 后端接口返回的为文件,前端如何下载(后端接口返回近万条数据,前端渲染缓慢,content Download 时间长的优化方案)