一、找出单链表的倒数第K个元素(仅容许遍历一遍链表)
使用指针追赶的方法。定义两个指针fast和slow,fast先走K步,而后fast和slow同时继续走。当fast到链表尾部时,slow指向倒数第K个。注意要考虑链表长度应该大于K。
二、找出单链表的中间元素(仅容许遍历一遍链表)
使用指针追赶的方法。fast每次走一步,slow每次走两步。当fast到链表尾部时,slow指向链表的中间元素。
三、判断单链表是否有环?
方法一:使用指针追赶的方法。slow指针每次走一步,fast指针每次走两步。如存在环,则二者相遇;如不存在环,fast遇到NULL退出。
方法二:使用p、q两个指针,p老是向前走,但q每次都从头开始走。
四、如何知道环的长度?
记录下碰撞点(或者找在环中任意一结点均可以),让slow从碰撞点开始,绕着环走一圈,再次到碰撞点的位置时,所走过的结点数就是环的长度s。
五、如何找到环的入口?
分别从碰撞点、头指针开始走,相遇的那个点就是链接点。
六、判断两个链表(无环)是否相交?
方法一:采用暴力的方法,遍历两个链表,在遍历的过程当中进行比较,看节点是否相同。
方法二:两链表一旦相交,相交节点必定有相同的内存地址,所以利用内存地址创建哈希表,如此经过判断两个链表中是否存在内存地址相同的节点判断两个链表是否相交。具体作法是:遍历第一个链表,并利用地址创建哈希表,遍历第二个链表,看看地址哈希值是否和第一个表中的节点地址值有相同便可判断两个链表是否相交。时间复杂度O((length(A)+ length(B))
方法三:问题转化法。先遍历第一个链表到其尾部,而后将尾部的本来指向NULL的next指针指向第二个链表。这样两个链表就合成了一个链表,问题转变为判断新的链表是否有环?
方法四:一旦两个链表相交,那么两个链表从相交节点开始到尾节点必定都是相同的节点。因此,若是他们相交的话,那么他们最后的一个节点必定是相同的,所以分别遍历到两个链表的尾部,而后判断他们是否相同。
七、如何知道两个单链表(可能有环)是否相交
思路:根据两个链表是否有环来分别处理,若相交这个环属于两个链表共有
(1)若是两个链表都没有环。
(2)一个有环,一个没环。确定不相交
(3)两个都有环。
①求出A的环入口,判断其是否在B链表上,若是在,则相交。
② 在A链表上,使用指针追赶的方法,找到两个指针碰撞点,以后判断碰撞点是否在B链表上。若是在,则相交。
八、寻找两个相交链表的第一个公共节点
方法一:最简单的方法就是先顺序访问其中一个链表,在每访问一个节点时,都对另一个链表进行遍历,直到找到一个相等的节点位置,若是链表长度分别是m,n 则时间复杂度为O(mn)。
方法二:(两种状况)
① 相交的点,在环外。若是两个链表有公共节点,那么该公共节点以后的全部节点都是两个链表所共有的,因此长度必定也是相等的,若是两个链表的总长度是相等的,那么咱们对两个链表进行遍历,则必定同时到达第一个公共节点。可是链表的长度实际上不必定相同,因此计算出两个链表的长度之差n,而后让长的那个链表先移动n步,短的链表再开始向后遍历,这样他们必定同时到达第一个公共节点,咱们只须要在向后移动的时候比较两个链表的节点是否相等就能够得到第一个公共节点。时间复杂度是O(m+n)。
② 相交的点在环内。当交点在环中时,此时的交点能够是A链表中的环入口点,也能够是B链表中环入口点。这是由于若是把B看出一个完整的链表,而A指向了B链表,则此时交点是A的环入口点。反之交点是链表B的环入口点。
思路:根据上述分析,能够直接求出A的环入口点或者B的环入口点就能够了。