求链表的中间节点/倒数第K个节点
等类似的随机访问,可以考虑用快慢指针
例
求链表的中间节点
可以定义两个指针,一个一次走两步一个一次走一步,当走的快的走到NULL时,走的慢的就是链表的中间节点。(此法求出的偶数个节点的链表的中间节点是它中间的第二个)
求倒数第K个节点,也可以定义两个指针,然后一个先走K步,走完以后,另一个再走
判断是否为回文链表
先用快慢指针求中间节点
逆置中间节点及其后的节点,并用一个指针指向该逆置后的链表
头指针和指向该逆置后的链表的指针一起走并比较是否相等,有一个不相等就不是回文链表
有一个链表走到NULL就停下,并且该链表是回文链表(因为中间节点的前一个结点还指向逆置后的最后一个节点)
判断两个链表是否相交,并且求出第一个相交的节点
如果相交这两个链表的尾节点一定相等
如果两个链表的尾节点相等,就求出两个链表的长度
让长的先走这两个链表长度的差值步,然后一起走
走到两个链表的节点的指针域第1次相等的地方,就是第一个相交的节点
判断链表是否带环
(用快慢指针,一个走一次走两步,一个一次走一步)
由于快指针与慢指针走的步数差为1(步数差=快指针一次走的步数—慢指针一次走的步数),所以如果链表带环,慢指针最终一定会追上快指针,反之则不会。
如果快指针与慢指针走的步数差为1(步数差=快指针一次走的步数—慢指针一次走的步数)则快慢指针一定会再环中相遇
因为
则设快指针入和慢指针入环后的差距为N,
如果快指针与慢指针走的步数差为1
那么他们两个指针每走一次,N就减1,当N为0时就相遇了
如果快指针与慢指针走的步数差不为1
就要看N是不是他们两个的差值的倍数了,
如果不是就要看N减到负数时新的N是不是他们两个都倍数,如果还不是,就肯定追不上了。
求带环链表的入环节点
结论:快指针从相遇点开始走,慢指从链表的头开始走,他们会在环的入口点相遇
把快慢指针的相遇点指向NULL,让一个新的指针指向相遇点的下一个节点,让这个新的指针一步一步向后走,再让一个指针原链表的头开始走,这两个链表的交点就是链表入环点
复制复杂链表问题
(复杂链表是多了一个随机指针,这个指针可能指向他自己这个链表的任何一个节点,也可能指向NULL)
时间复杂度为O(N)的方法
在原链表的每一个节点后面插入malloc一个新节点,这个新节点复制了它前一个节点的数据域。
这个新节点的随机指针指向它前一个节点的随机指针指向的节点的next,如下图
最后把新的malloc出来的节点连接起来,再把原链表恢复