一、前言
链表是数据结构中重要的一个章节,他的重要性也不言而喻,在未来不管是笔试还是面试都会遇到这类的题目,所以接下来我就会把一些链表的常考的题目全部整理出来供大家学习指正。
二、学习刷题网站
点击下面链接即可进行刷题学习
开始刷题
1.推荐的原因
刷题网站何其多,但好的刷题网站却不多,以下几点就是我推荐的原因:
1️⃣全面
里面有很多资料,不管是刷题还是学习还是面经等等
2️⃣大众
首先用的人很多,可以看到很多的题解,其次如果有问题也会有很多人回答
3️⃣熟悉oj环境
我们以后找工作的时候很多公司都会用这个网站,我们可以提前熟悉环境
三、刷题
先说明一下一些题目取自牛客网面试必刷TOP101
里面的一些题目在我以前的文章详细写到过,如果没有用新的方法就不会再做讲解
链表题目(一)
链表题目(二)
环状链表
<1>反转链表
题目链接
描述:
给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。
数据范围:0 ≤ n ≤ 1000
要求:空间复杂度 O(1) ,时间复杂度 O(n) 。
如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:
示例1:
输入:{1,2,3}
返回值:{3,2,1}
示例2:
输入:{}
返回值:{}
说明:空链表则输出空
思路分析:
以前的文章里面讲过两个方法:
1.暴力改方向,三指针直接改
2.头插法
这里讲一下新方法:
递归法
递归主要是要把大事化小。用第一个元素来说,假设后面已经逆序,把后面的所有元素当成一个整体,把第一个元素移到最后就完成了逆序。然后继续第二个第三个元素递归下去,最终完成逆序。
而递归最重要的是结束条件,当递归到最后一个元素就已经全部完成了逆序。
struct ListNode* ReverseList(struct ListNode* pHead ) {
// write code here
if(pHead == NULL || pHead->next == NULL)
{
return pHead;
}
struct ListNode* tmp = ReverseList(pHead->next);
pHead->next->next = pHead;
pHead->next = NULL;
return tmp;
}
这里注意pHead->next
每次都是指向tmp链表的最后一个元素。
<2>链表内指定区间反转
题目链接
描述:
将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度 O(n),空间复杂度 O(1)。
例如:
给出的链表为1→2→3→4→5→NULL, m=2,n=4
返回 1→4→3→2→5→NULL
数据范围: 链表长度 0 < size ≤ 1000,0 < m ≤ n ≤ size,链表中每个节点的值满足∣val∣ ≤ 1000
要求:时间复杂度 O(n) ,空间复杂度 O(n)
进阶:时间复杂度 O(n),空间复杂度 O(1)
示例1:
输入:{1,2,3,4,5},2,4
返回值:{1,4,3,2,5}
示例2:
输入:{5},1,1
返回值:{5}
思路分析:
①头插法
思路大体可以分为三个步骤
1️⃣ 先创建一个前序头指针,为了防止第一个元素也要逆序。
2️⃣用双指针prev和cur找到m的位置,prev就指向m的前一个位置,方便把cur的下一个元素移动到cur的前面
3️⃣对于从m到n这些个位置的节点,依次断掉指向后续的指针,反转指针方向。