更新链表总结篇

This commit is contained in:
youngyangyang04
2021-05-18 15:34:44 +08:00
parent 17f416c71d
commit 0e783a92db

View File

@ -7,11 +7,10 @@
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
> 之前链表篇没有做总结,所以是时候总结一波
# 链表的理论基础
## 链表的理论基础
在这篇文章[关于链表,你该了解这些!](https://mp.weixin.qq.com/s/ntlZbEdKgnFQKZkSUAOSpQ)中,介绍了如下几点:
在这篇文章[关于链表,你该了解这些!](https://mp.weixin.qq.com/s/fDGMmLrW7ZHlzkzlf_dZkw)中,介绍了如下几点:
* 链表的种类主要为:单链表,双链表,循环链表
* 链表的存储方式:链表的节点在内存中是分散存储的,通过指针连在一起。
@ -20,21 +19,21 @@
**可以说把链表基础的知识都概括了,但又不像教科书那样的繁琐**
# 链表经典题目
## 链表经典题目
## 虚拟头结点
### 虚拟头结点
在[链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/slM1CH5Ew9XzK93YOQYSjA)中,我们讲解了链表操作中一个非常总要的技巧:虚拟头节点。
在[链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/L5aanfALdLEwVWGvyXPDqA)中,我们讲解了链表操作中一个非常总要的技巧:虚拟头节点。
链表的一大问题就是操作当前节点必须要找前一个节点才能操作。这就造成了,头结点的尴尬,因为头结点没有前一个节点了。
**每次对应头结点的情况都要单独处理,所以使用虚拟头结点的技巧,就可以解决这个问题**
在[链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/slM1CH5Ew9XzK93YOQYSjA)中,我给出了用虚拟头结点和没用虚拟头结点的代码,大家对比一下就会发现,使用虚拟头结点的好处。
在[链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/L5aanfALdLEwVWGvyXPDqA)中,我给出了用虚拟头结点和没用虚拟头结点的代码,大家对比一下就会发现,使用虚拟头结点的好处。
## 链表的基本操作
### 链表的基本操作
在[链表:一道题目考察了常见的五个操作!](https://mp.weixin.qq.com/s/Cf95Lc6brKL4g2j8YyF3Mg)中,我们通设计链表把链表常见的五个操作练习了一遍。
在[链表:一道题目考察了常见的五个操作!](https://mp.weixin.qq.com/s/jnC_LAD0ZKCsj-FZc57F1g)中,我们通设计链表把链表常见的五个操作练习了一遍。
这是练习链表基础操作的非常好的一道题目,考察了:
@ -48,103 +47,49 @@
这里我依然使用了虚拟头结点的技巧,大家复习的时候,可以去看一下代码。
## 反转链表
### 反转链表
在[链表:听说过两天反转链表又写不出来了?](https://mp.weixin.qq.com/s/pnvVP-0ZM7epB8y3w_Njwg)中,讲解了如何反转链表。
在[链表:听说过两天反转链表又写不出来了?](https://mp.weixin.qq.com/s/ckEvIVGcNLfrz6OLOMoT0A)中,讲解了如何反转链表。
因为反转链表的代码相对简单,有的同学可能直接背下来了,但一写还是容易出问题。
反转链表是面试中高频题目,很考察面试者对链表操作的熟练程度。
我在[文章](https://mp.weixin.qq.com/s/pnvVP-0ZM7epB8y3w_Njwg)中,给出了两种反转的方式,迭代法和递归法。
我在[文章](https://mp.weixin.qq.com/s/ckEvIVGcNLfrz6OLOMoT0A)中,给出了两种反转的方式,迭代法和递归法。
建议大家先学透迭代法,然后再看递归法,因为递归法比较绕,如果迭代还写不明白,递归基本也写不明白了。
**可以先通过迭代法,彻底弄清楚链表反转的过程!**
### 删除倒数第N个节点
在[链表删除链表倒数第N个节点怎么删](https://mp.weixin.qq.com/s/gxu65X1343xW_sBrkTz0Eg)中我们结合虚拟头结点 和 双指针法来移除链表倒数第N个节点。
### 链表相交
[链表:链表相交](https://mp.weixin.qq.com/s/BhfFfaGvt9Zs7UmH4YehZw)使用双指针来找到两个链表的交点(引用完全相同,即:内存地址完全相同的交点)
## 环形链表
在[链表:环找到了,那入口呢?](https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA)中,讲解了在链表如何找环,以及如何找环的入口位置。
在[链表:环找到了,那入口呢?](https://mp.weixin.qq.com/s/gt_VH3hQTqNxyWcl1ECSbQ)中,讲解了在链表如何找环,以及如何找环的入口位置。
这道题目可以说是链表的比较难的题目了。
这道题目可以说是链表的比较难的题目了。 但代码却十分简洁,主要在于一些数学证明。
很多同学关注的问题是:为什么一定会相遇,快指针就不能跳过慢指针么?
可以确定如下两点:
* 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='https://code-thinking.cdn.bcebos.com/pics/142%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A85.png' width=600> </img></div>
首先slow进环的时候fast一定是先进环来了。
如果slow进环入口fast也在环入口那么把这个环展开成直线就是如下图的样子
<img src='https://code-thinking.cdn.bcebos.com/pics/142%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A83.png' width=600> </img></div>
可以看出如果slow 和 fast同时在环入口开始走一定会在环入口3相遇slow走了一圈fast走了两圈。
重点来了slow进环的时候fast一定是在环的任意一个位置如图
<img src='https://code-thinking.cdn.bcebos.com/pics/142%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A84.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)
1. [关于链表,你该了解这些!](https://mp.weixin.qq.com/s/fDGMmLrW7ZHlzkzlf_dZkw)
2. [虚拟头结点的技巧](https://mp.weixin.qq.com/s/L5aanfALdLEwVWGvyXPDqA)
3. [链表的增删改查](https://mp.weixin.qq.com/s/jnC_LAD0ZKCsj-FZc57F1g)
4. [反转一个链表](https://mp.weixin.qq.com/s/ckEvIVGcNLfrz6OLOMoT0A)
5. [删除倒数第N个节点](https://mp.weixin.qq.com/s/gxu65X1343xW_sBrkTz0Eg)
6. [链表相交](https://mp.weixin.qq.com/s/BhfFfaGvt9Zs7UmH4YehZw)
7. [有否环形,以及环的入口](https://mp.weixin.qq.com/s/gt_VH3hQTqNxyWcl1ECSbQ)
虽然这几篇文章都是几个月前发的了,但在在文章留言区,可以看到很多录友都在从头打卡!
如果希望从基础学起来的同学,也可以从头学起来,从头开始打卡,打卡的同时也总结自己的所学所思,一定进步飞快!
## 其他语言版本
Java
Python
Go