forked from youngyangyang04/leetcode-master
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
60fa8d0
commit bce1762
Showing
6 changed files
with
135 additions
and
11 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,131 @@ | ||
> 之前链表篇没有做总结,所以是时候总结一波 | ||
> 链表理论基础 | ||
# 链表的理论基础 | ||
|
||
在这篇文章[关于链表,你该了解这些!](https://mp.weixin.qq.com/s/ntlZbEdKgnFQKZkSUAOSpQ)中,介绍了如下几点: | ||
|
||
* [关于链表,你该了解这些!](https://mp.weixin.qq.com/s/ntlZbEdKgnFQKZkSUAOSpQ) | ||
* [链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/slM1CH5Ew9XzK93YOQYSjA) | ||
* [链表:一道题目考察了常见的五个操作!](https://mp.weixin.qq.com/s/Cf95Lc6brKL4g2j8YyF3Mg) | ||
* [链表:听说过两天反转链表又写不出来了?](https://mp.weixin.qq.com/s/pnvVP-0ZM7epB8y3w_Njwg) | ||
* [链表:环找到了,那入口呢?](https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA) | ||
* 链表的种类主要为:单链表,双链表,循环链表 | ||
* 链表的存储方式:链表的节点在内存中是分散存储的,通过指针连在一起。 | ||
* 链表是如何进行增删改查的。 | ||
* 数组和链表在不同场景下的性能分析。 | ||
|
||
**可以说把链表基础的知识都概括了,但又不像教科书那样的繁琐**。 | ||
|
||
# 链表经典题目 | ||
|
||
## 虚拟头结点 | ||
|
||
在[链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/slM1CH5Ew9XzK93YOQYSjA)中,我们讲解了链表操作中一个非常总要的技巧:虚拟头节点。 | ||
|
||
链表的一大问题就是操作当前节点必须要找前一个节点才能操作。这就造成了,头结点的尴尬,因为头结点没有前一个节点了。 | ||
|
||
**每次对应头结点的情况都要单独处理,所以使用虚拟头结点的技巧,就可以解决这个问题**。 | ||
|
||
在[链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/slM1CH5Ew9XzK93YOQYSjA)中,我给出了用虚拟头结点和没用虚拟头结点的代码,大家对比一下就会发现,使用虚拟头结点的好处。 | ||
|
||
## 链表的基本操作 | ||
|
||
在[链表:一道题目考察了常见的五个操作!](https://mp.weixin.qq.com/s/Cf95Lc6brKL4g2j8YyF3Mg)中,我们通设计链表把链表常见的五个操作练习了一遍。 | ||
|
||
这是练习链表基础操作的非常好的一道题目,考察了: | ||
|
||
* 获取链表第index个节点的数值 | ||
* 在链表的最前面插入一个节点 | ||
* 在链表的最后面插入一个节点 | ||
* 在链表第index个节点前面插入一个节点 | ||
* 删除链表的第index个节点的数值 | ||
|
||
**可以说把这道题目做了,链表基本操作就OK了,再也不用担心链表增删改查整不明白了**。 | ||
|
||
这里我依然使用了虚拟头结点的技巧,大家复习的时候,可以去看一下代码。 | ||
|
||
## 反转链表 | ||
|
||
在[链表:听说过两天反转链表又写不出来了?](https://mp.weixin.qq.com/s/pnvVP-0ZM7epB8y3w_Njwg)中,讲解了如何反转链表。 | ||
|
||
因为反转链表的代码相对简单,有的同学可能直接背下来了,但一写还是容易出问题。 | ||
|
||
反转链表是面试中高频题目,很考察面试者对链表操作的熟练程度。 | ||
|
||
我在[文章](https://mp.weixin.qq.com/s/pnvVP-0ZM7epB8y3w_Njwg)中,给出了两种反转的方式,迭代法和递归法。 | ||
|
||
建议大家先学透迭代法,然后再看递归法,因为递归法比较绕,如果迭代还写不明白,递归基本也写不明白了。 | ||
|
||
**可以先通过迭代法,彻底弄清楚链表反转的过程!** | ||
|
||
## 环形链表 | ||
|
||
在[链表:环找到了,那入口呢?](https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA)中,讲解了在链表如何找环,以及如何找环的入口位置。 | ||
|
||
这道题目可以说是链表的比较难的题目了。 | ||
|
||
很多同学关注的问题是:为什么一定会相遇,快指针就不能跳过慢指针么? | ||
|
||
可以确定如下两点: | ||
|
||
* fast指针一定先进入环中,如果fast 指针和slow指针相遇的话,一定是在环中相遇,这是毋庸置疑的。 | ||
* fast和slow都进入环里之后,fast相对于slow来说,fast是一个节点一个节点的靠近slow的,**注意是相对运动,所以fast一定可以和slow重合**。 | ||
|
||
如果fast是一次走三个节点,那么可能会跳过slow,因为相对于slow来说,fast是两个节点移动的。 | ||
|
||
确定有否有环比较容易,但是找到环的入口就不太容易了,需要点数学推理。 | ||
|
||
我在[链表:环找到了,那入口呢?](https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA)中给出了详细的推理,兼顾易懂和简洁了。 | ||
|
||
这是一位录友在评论区有一个疑问,感觉这个问题很不错,但评论区根本说不清楚,我就趁着总结篇,补充一下这个证明。 | ||
|
||
在推理过程中,**为什么第一次在环中相遇,slow的 步数 是 x+y 而不是 x + 若干环的长度 + y 呢?** | ||
|
||
了解这个问题一定要先把文章[链表:环找到了,那入口呢?](https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA)看了,即文章中如下的地方: | ||
|
||
<img src='../pics/142环形链表5.png' width=600> </img></div> | ||
|
||
|
||
首先slow进环的时候,fast一定是先进环来了。 | ||
|
||
如果slow进环入口,fast也在环入口,那么把这个环展开成直线,就是如下图的样子: | ||
|
||
<img src='../pics/142环形链表3.png' width=600> </img></div> | ||
|
||
可以看出如果slow 和 fast同时在环入口开始走,一定会在环入口3相遇,slow走了一圈,fast走了两圈。 | ||
|
||
重点来了,slow进环的时候,fast一定是在环的任意一个位置,如图: | ||
|
||
<img src='../pics/142环形链表4.png' width=600> </img></div> | ||
|
||
那么fast指针走到环入口3的时候,已经走了k + n 个节点,slow相应的应该走了(k + n) / 2 个节点。 | ||
|
||
因为k是小于n的(图中可以看出),所以(k + n) / 2 一定小于n。 | ||
|
||
**也就是说slow一定没有走到环入口3,而fast已经到环入口3了**。 | ||
|
||
这说明什么呢? | ||
|
||
**在slow开始走的那一环已经和fast相遇了**。 | ||
|
||
那有同学又说了,为什么fast不能跳过去呢? 在刚刚已经说过一次了,**fast相对于slow是一次移动一个节点,所以不可能跳过去**。 | ||
|
||
好了,这次把为什么第一次在环中相遇,slow的 步数 是 x+y 而不是 x + 若干环的长度 + y ,用数学推理了一下,算是对[链表:环找到了,那入口呢?](https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA)的补充。 | ||
|
||
这次可以说把环形链表这道题目的各个细节,完完整整的证明了一遍,说这是全网最详细讲解不为过吧,哈哈。 | ||
|
||
# 总结 | ||
|
||
考察链表的操作其实就是考察指针的操作,是面试中的常见类型。 | ||
|
||
链表篇中开头介绍[链表理论知识](https://mp.weixin.qq.com/s/slM1CH5Ew9XzK93YOQYSjA),然后分别通过经典题目介绍了如下知识点: | ||
|
||
* [虚拟头结点的技巧](https://mp.weixin.qq.com/s/slM1CH5Ew9XzK93YOQYSjA) | ||
* [链表的增删改查](https://mp.weixin.qq.com/s/Cf95Lc6brKL4g2j8YyF3Mg) | ||
* [反转一个链表](https://mp.weixin.qq.com/s/pnvVP-0ZM7epB8y3w_Njwg) | ||
* [有否环形,以及环的入口](https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA) | ||
|
||
虽然这几篇文章都是几个月前发的了,但在在文章留言区,可以看到很多录友都在从头打卡! | ||
|
||
如果希望从基础学起来的同学,也可以从头学起来,从头开始打卡,打卡的同时也总结自己的所学所思,一定进步飞快! | ||
|
||
**在公众号左下方,「算法汇总」可以找到历史文章,都是按系列排好顺序的,快去通关学习吧!** | ||
|
||
![](https://img-blog.csdnimg.cn/20201030210901823.jpg) | ||
|
||
**「代码随想录」这么用心的公众号,不分享给身边的同学朋友啥的,是不是可惜了? 哈哈** |