问题1: 如何判断单链表是否存在环?
两个指针p1,p2,p1走一步,p2走两步,判断是否两指针是否会想交。
问题2:如果存在环,如何找到环的入口?
思路1:
依然使用两个指针p1,p2,p1走一步,p2走两步。
如果存在环,不妨假设环的长度为m,链表头结点到环的入口长度为c。则p2比p1先c步进入环。
此时,可以看成操场上赛跑的问题,两个人绕长为m的操场跑步,p2的速度是p1的两倍,p1在起跑点,p2比p1点超c步;则p2离p1的距离为m-c步,p2追上p1时(注意p1每走一步,p2则离他的距离就缩小一步),p1刚好走了m-c步。所以p2追上p1时,p1离起跑点的距离为c步。(假设m>c,否则计算中可以应用c%m得到同样结果)
p1与p2交点离环的入口点的距离,刚好等于链表的起点到环的入口点的距离!!多奇妙的结论!
思路2:
可以看成两个单链表求第一个公共交点的问题。
取p1与p2的交点为p,问题转换为p为头结点的链表与原链表的第一个交点(具体可参看问题四的解答)。
问题3:两个单链表,如何判断两链表是否有公共交点?
思路1:
有公共交点,则最后的结点必然是链表的公共交点,故只需判断最后一个结点是否相同即可。
思路2:
可将两个链表连接成一个链表,转换成链表求环的问题。具体可看前两个问题的解答。
问题4:如果存在交点,如何求出第一个交点?
思路1:
设链表1长度为l1,链表2的长度为l2,如果存在公共交点,则从两个链表的第一个交点到最后一个交点都会相同,而第一个交点可能的位置,在l2中为l2-l1 =》 l2(取l2的长度大于l1的长度),只需依次比较l2中l2-l1 => l2 与l1中 1=>l1的对应位置,找到第一个相同的点,即为第一个交点。
思路2:
可将两个链表连接成一个链表,转换成链表求环的问题。具体可看前两个问题的解答。
问题5:一个特殊的应用,在二叉树中,找出两个节点的第一个公共祖先
思路:
将从节点到根节点链接路径看成是一个链表,问题转换为求两个单链表的第一个公共节点。