您现在的位置是:首页 >技术杂谈 >学习数据结构(7)单链表OJ下+链表分类网站首页技术杂谈

学习数据结构(7)单链表OJ下+链表分类

lxl1307 2025-05-14 00:01:04
简介学习数据结构(7)单链表OJ下+链表分类

1.链表的回文结构

解法一:(投机取巧的办法)由于题目中保证链表长度小于等于900,所以可以创建一个长度为900的数组,通过遍历将链表中的数据依次储存到数组中,再在左下标小于等于右下标的情况下,从数组两端同时遍历,若数组元素不相等,返回false,否则返回true

解法二:(参考解法)先找到链表的中间节点,以中间节点为首节点,将首节点以后的链表反转,得到新的首节点,分别从原链表的首节点和新的首节点开始,在新的首节点不为NULL的条件下同时遍历,如果节点储存的数据不相等,返回false,否则返回true

2.相交链表

解法一:(参考解法)由于两个链表的长度不确定,所以不能直接同时遍历两个链表,可以先分别遍历两个链表,求出两个链表相差的长度,让长链表先走,对齐长度,再同时遍历两个链表,如果有链表储存的数据不同,返回flase,否则返回true

(另外还有一种思路,将两个链表反转,从反转后的首节点开始同时遍历,若某个节点的next不同,则返回这个节点,但题目中要求,所以本题不考虑)

3.环形链表Ⅰ

解法一:(快慢指针)

首先必须证明一个结论:在环形链表中,快慢指针同时从链表起始位置开始运动,其中慢指针一次走一步,快指针一次走两步, 快慢指针一定会相遇

假设slow刚到入环节点时,fast在如图所示的位置,此时fast与slow之间的距离为N,由于fast每次走两步,slow每次走一步,所以每运动一次fast和slow之间的距离就会减少一步,故只要运动的次数足够多,fast和slow之间的距离一定会减为0,即fast和slow相遇

所以让fast和slow在fast和fast->next同时存在的情况下,同时从首节点开始运动,如果出现fast==slow,则返回true,否则返回false

快指针如果一次走3步、4步、5步……n步,快慢指针都一定会相遇吗?

下面证明快指针走三步的情况:

C为环形部分的周长,假设slow刚到入环节点时,fast在如图所示的位置,此时fast与slow之间的距离为N,由于fast每次走三步,slow每次走一步,所以每运动一次fast和slow之间的距离就会减少两步,若N为偶数,则N不断减2最终可以为0,即fast和slow相遇,若N为奇数,N会减为-1,此时slow和fast错过,fast和slow之间的距离变为C-1,若C-1为偶数(即C为奇数),则fast和slow可以相遇,若C-1为奇数(即C为偶数),则fast和slow还是不能相遇,最终也不会相遇

由于fast每次走三步。slow每次走一步,所以fast的总路程一定是slow的三倍,如上图所示,此时fast的路程为L+xC+C-N,slow的路程为L,代入关系式,得2L=(x+1)C-N

对上式进行分析,2L是偶数,偶数=偶数-偶数或奇数-奇数,当(x+1)C为奇数,N为奇数时,由于奇数只可能等于奇数×奇数,所以(x+1)一定为奇数,C也一定为奇数,故N为奇数,C为偶数的情况不存在,也就是说,只存在两种情况:N为偶数,C为奇数;N为奇数,C为奇数,故fast和slow一定会相遇

其他情况的证明方法同上

在环形链表中,slow一次走一步,无论fast一次走多少步,fast和slow最终一定会相遇

fast走三步时的代码:

为了方便写代码,通常使用快指针走两步,慢指针走一步即可

4.环形链表Ⅱ

解法一:(参考解法)解这道题之前首先得证明一个结论:快慢指针相遇点(即判环点)到入环口的距离与链表起始点到入环口的距离相等

相遇时快指针走的总路程为L+C-N+xC,慢指针走的总路程为L+C-N,由于快指针所走路程为慢指针的两倍,代入关系式,得L=xC-(C-N)=(x-1)C+N(x=1,2,3....,x的值取决于环的大小,环越小x越大),取x=1,得L=N,即链表起点到入环点的距离与相遇点到入环点的距离相等

也就是说,如果一个指针从链表起点开始运动,同时另一个指针从相遇点开始运动,都一次走一步,那么这两个指针最终会在入环点相遇

参考代码:

5.链表的分类

链表的结构虽然有八种,但最常用的还是不带头单向不循环链表和带头双向循环链表,头节点指的是不储存数据的节点(哨兵位),不带头单向不循环链表结构简单,一般不单独用来储存数据,带头双向循环链表结构最复杂,一般用在单独储存数据

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。