LeetCode题解

  • 1、2095. 删除链表的中间节点
  • 2、 删除链表的倒数第 N 个结点
  • 3、排序链表

1、2095. 删除链表的中间节点

题目描述:

➡️挑战链接⬅️
分析:
首先题目要求我们删除中间节点,我们知道单链表是单向性的不能回头的,那么当我们找到中间节点时,也应该用一个变量记录一下它的前一个节点,这样便于将删除中间节点过后的两部分节点,连接起来;
那么我们怎么找到中间节点?
当然对于本题来说,头节点是可能变化的,为了避免单独对于头节点的讨论,我们可以定义一个虚拟头节点(哑节点);对于寻找中间节点的位置
我们可以利用快慢指针的办法来寻求帮助:具体办法如下:
我们每次让fast指针走2步,让slow指针走1步:
那么到什么时候停止向前走?

通过上面图片分析我们可以看出当fast->next==NULL时,我们就可以停止向前走了,这时候slow指针刚好指向中间节点,而我们的prev节点也是刚好指向中间节点的前一个节点;
这时就已经万事俱备了,只需我们去删除掉中间节点了;
为了验证我们上面的条件,我们再来一组数据看看是不是再上面也满足上面的条件;

我们可以发现这时候上面推出的条件,再这里好像不适用了,其实并不是,我们可以通过对比两幅图可以看到,上一幅图有奇数个节点,下一幅图有偶数个节点;由于奇偶的限制,这就必然导致我虽然每次fast都走两步,slow走一步,但是我停下来的条件不一样;
综上:我们可以得出fast指针停下来的条件:奇数个节点:fast->next==NULL;偶数个节点:fast=NULL
最后不管是以如何方式停下来的,我们的slow都是指向中间节点的,因此接下来,我们对链表进行节点的删除操作都是一样的;
➡️ 代码实现: ⬅️

struct ListNode* deleteMiddle(struct ListNode* head){struct ListNode*slow=head;struct ListNode*fast=head;struct ListNode tmp={0};struct ListNode*dummyheda=&tmp;//头指针也有可能改变,设置哑节点dummyheda->next=slow;struct ListNode*prev=dummyheda;//slow前一个指针while(fast&&fast->next)//fast终止条件{fast=fast->next->next;prev=slow;slow=slow->next;}prev->next=slow->next;//删除中间节点
return dummyheda->next;
}

时间复杂度:O(N)
空间复杂度:O(1)

2、 删除链表的倒数第 N 个结点

题目描述:

➡️ 挑战链接 ⬅️
分析:
同样这道题也可以用快慢指针来解决,首先题目要求我们要删除倒数第k个节点,那么从另一个方面来说是不是我的slow指针和fast指针之间相差的有k个节点;就好比两个人跑步(直道):甲从起点开始跑,乙从距离起点k米位置开始跑,同时甲乙两人速度大小完全一样,那么是不是说明甲乙两人永远不会相遇,并且甲乙之间的距离会一直保持在k米,不会多也不会少,一直都是这么多,然后呢,结果肯定是乙先跑到终点,当然在乙到达终点时,此时甲还没哟到达终点,并且与乙之间还保持着k米的距离,那么这时候我们是不是就可以说甲在距离终点k米的位置(也就是倒数k米的位置);
然后现在对比回来我们的链表就相当于直跑道,fast就是乙,slow就是甲,终点就是NULL,
当然为了得到甲与乙之间k个距离,我们先让fast指针跑个k个距离,然后再一起跑是不是就是上面例子的思路:

当然我们定义哑节点的目的就是为了处理头节点被删除的情况,prev指针表示slow的前一个指针;
当然题目保证了k是再合法范围内的,不会超过链表长度,也不会等于负数和0;
➡️ 代码实现: ⬅️


struct ListNode* removeNthFromEnd(struct ListNode* head, int n){if(!head)//对于空白节点单独处理return head;struct ListNode*dummyhead=(struct ListNode*)malloc(sizeof(struct ListNode));dummyhead->next=head;struct ListNode*prev=dummyhead;struct ListNode*slow=head;struct ListNode*fast=head;while(n--)//fast指针先走n步,与slow保持一定距离fast=fast->next;while(fast)//fast和slow一起以相同速度跑{fast=fast->next;prev=slow;slow=slow->next;}prev->next=slow->next;//删除节点return dummyhead->next;
}

时间复杂度:O(N)
空间复杂度:O(1)

3、排序链表

题目描述:

➡️ 挑战链接 ⬅️
分析:
题目大概意思就是对链表进行重新排序,我们知道对于数组来说,它拥有很多种排序的方法,这主要是由于其结构决定的,但是对于单链表来说它不能回头,只能往前走,因此对于这样的话许多优秀的排序算法对于链表操作起来难度就更大了;因此呢我们能不能将单链表转换为数组呢?
当然可以,我们可以把单链表的每个节点剪下来,然后存放在一个数组里面,然后再根据节点里面的值(val)来对这个数组进行排序,最后呢再将链表连接起来;这样的思路固然可行,但是对于这道题来说总感觉有一点违背题意的意思;
因此我们可以换个思路,我们可以借用归并排序的思想对于链表进行排序:
首先我们来回忆一下归并排序对于数组是怎么处理的:
首先归并排序的主要思想就是对于有序数组进行选值,先放进临时数组,然后再有临时数组拷贝回原数组:
大概思路:

换而言之,我们如果相对单链表也按照这样的思想进行排序的话,我们是不是得对有序单链表进行合并(有序单链表的合并)


可是现在我们怎么让链表变为两个有序的子链表?
按照归并的思路,我们可以对链表不断的二分;
最后分到只有一个节点,是不是就可以认为他是有序的了,我们是不是就可以对其进行操作了;
当然合并过后会产生一个新的有序链表,我们又利用这个有序链表继续合并成一个更大的有序链表;
最终链表不就有序了嘛;
➡️ 代码实现: ⬅️

struct ListNode*MergeList(struct ListNode*head)
{if(head->next==NULL)//只剩一个节点时停止递归,此时已经有序了return head;struct ListNode tmp={0};struct ListNode*dummyhead=&tmp;dummyhead->next=head;struct ListNode*prev=dummyhead;struct ListNode*slow=head;struct ListNode*fast=head;while(fast&&fast->next)//寻找中间链表,好把链表分组{fast=fast->next->next;prev=slow;slow=slow->next;}prev->next=NULL;//将2个链表分别单独出来;printf("head=%d slow=%d\n",head->val,slow->val);struct ListNode*NewHead1=MergeList(dummyhead->next);//head~NULLstruct ListNode*NewHead2=MergeList(slow);//slow~NULLstruct ListNode tmp2={0};struct ListNode*Newhead0=&tmp2;struct ListNode*cur=Newhead0;struct ListNode*next=NULL;while(NewHead1&&NewHead2)//开始给两个有序链表合并{if(NewHead1->val<=NewHead2->val){next=NewHead1->next;cur->next=NewHead1;cur=NewHead1;NewHead1=next;}else{next=NewHead2->next;cur->next=NewHead2;cur=NewHead2;NewHead2=next;}}if(NewHead1)cur->next=NewHead1;if(NewHead2)cur->next=NewHead2;return Newhead0->next;
}
struct ListNode* sortList(struct ListNode* head){if(!head)return head;return MergeList(head);
}

2095. 删除链表的中间节点、19. 删除链表的倒数第 N 个结点、148. 排序链表相关推荐

  1. [链表|多解法] leetcode 19 删除链表的倒数第N个节点

    [链表|多解法] leetcode 19 删除链表的倒数第N个节点 1.题目 题目链接 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2-&g ...

  2. 删除父节点子节点未删除的两种方法

    删除父节点子节点未删除的两种方法 平时所使用的tree删除父节点,子节点还保留在数据库. 删除前: 删除后: 父节点已删除,但数据库保留了子节点数据,以下有两种方法解决 方法一: 使用递归删除方法,我 ...

  3. 链表排序---迭代版本归并算法 + [leetcode]148. 排序链表

    前言: 对于链表来说,排序首选应该是归并算法 维基百科上有归并算法的迭代版本和递归版本 基于数组实现的. https://zh.wikipedia.org/wiki/%E5%BD%92%E5%B9%B ...

  4. LeetCode Algorithm 148. 排序链表

    148. 排序链表 Ideas 链表结构的经典题目. 不过我不想用经典方法做,哎,就是皮. 我把链表元素都拷贝到数组中,然后对数组排序,之后再把排完序之后的值赋回去. 骚的一批. Code Pytho ...

  5. 【LeetCode】【HOT】148. 排序链表(归并排序)

    [LeetCode][HOT]148. 排序链表 文章目录 [LeetCode][HOT]148. 排序链表 package hot;import java.util.Arrays;class Lis ...

  6. 1.删除链表的奇数节点 2.删除链表的偶数节点

    1.删除链表的奇数节点 /** 删除奇数节点*/public static ListNode deleteOddNode(ListNode head) {if (head == null)return ...

  7. 83. Leetcode 148. 排序链表 (排序)

    给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 .示例 1:输入:head = [4,2,1,3] 输出:[1,2,3,4] 示例 2:输入:head = [-1,5,3,4, ...

  8. Leetcode 148. 排序链表 解题思路及C++实现

    解题思路: 对链表进行归并排序,使用 fast 和 slow 两个指针,遍历一次链表,就能将链表切分为两半,然后使用归并排序的方法. /*** Definition for singly-linked ...

  9. 【编程4】插入排序+快速排序+LeetCode.148(排序链表)

    文章目录 一.排序链表 1.题目描述--LeetCode.148 2.分析 (1)一般的快排 (2)解题思路 3.实现 二.排序算法 三.插入排序 1.基本思想 (1)过程概述 (2)具体算法描述: ...

最新文章

  1. HALCON表面划痕检测
  2. 01H5-fe-html5-005插入音频
  3. jquery插件开发;(function ( $, window, document, undefined ){}(jQuery, window,document)分析
  4. matlab怎么载入视频,怎样将视频导入matlab啊
  5. SpringBoot 优雅的整合 Shiro
  6. 三星突然发布Galaxy S10 Lite和Note 10 Lite:有不同也有所同
  7. css 鼠标悬浮样式_【技术】CSS设置链接鼠标(失效)不能点样式
  8. golang基础语法
  9. win7小工具打不开_Win7系统电脑桌面双击快捷键方式图标没反应的解决办法
  10. EMNLP'21中预训练模型最新研究进展
  11. React Native 触摸事件处理详解
  12. Veritas Backup Exec 21.3 Multilingual (Windows)
  13. JDK与JRE各种版本下载地址
  14. 解密带星号手机号网页_外滩大会“硬核科技”解密:支付宝金融级业务的“定海神针”...
  15. stay hungry stay foolish原文_2020考研英语二大纲原文
  16. 花粉的基本功效(收藏)
  17. 杜邦接口还有一个跟他相反的叫什么_日本新晋网红“Imma”出道,虚拟技术还能玩出什么花样?...
  18. mediawiki修改用mysql数据库_修改MediaWiki的动态页面列表DPL设置降低MySQL负载
  19. python建站的缺点_记录一下自己的建站过程(三):Python与Django
  20. JoVE肿瘤转移专刊征稿,写方法拍视频教程发SCI

热门文章

  1. “乔帮主”的云技术实践绝学,“降云十八掌”
  2. Android逆向前期准备
  3. VM虚拟机Ubuntu 22.04 LVM磁盘扩容报错:GPT PMBR size mismatch (104857599 != 209715199) will be corrected by wri
  4. windows 操作系统中 各个DLL 作用简介
  5. 【重温经典】mini2440驱动程序之LED驱动(基于Linux-2.6.32.2)
  6. jar包、war包和ear包的介绍与区别
  7. 我们整理了2017年最新政府大数据应用案例!
  8. 敦煌——期待再次与你相遇
  9. Arctic Network题解+(最小生成树二次理解 )
  10. 谷歌经营之道(How Google Works )