环形链表II题目的思路探讨与源码
环形链表II的题目如下图,该题属于哈希表和链表类型的题目,主要考察对于哈希表和链表的使用理解和认识。本文的题目作者想到2种方法,第一种方法是快慢指针方法,第二种方法是哈希表方法。其中第一种方法使用java写、第二种方法使用Python写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
本人认为该题目可以使用快慢指针的算法,首先判断链表是否为空,如果是空直接返回结果。然后开始初始化,把快慢指针的初始位置都设置在链表的头部位置,下面开始遍历。首先在循环开始的时候,先把慢指针移动到下一个节点,然后判断快指针的下一个节点是否为空,不为空的话就把快指针移动到下一个节点的下一个节点,也就是移动2步,下面判断快指针和慢指针是否相等,如果相等就把链表的头部赋值给一个标记节点记录,然后循环判断标记阶段是否和慢指针相等,如果不相等就把标记节点移动到下一个节点,并且把慢指针移动到下一个节点。那么按照这个思路我们的Java代码如下:
#喷火龙与水箭龟
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head == null){
return null;
}
ListNode aIndex = head;
ListNode bIndex = head;
while(bIndex != null){
aIndex = aIndex.next;
if(bIndex.next != null){
bIndex = bIndex.next.next;
}else{
return null;
}
if(aIndex == bIndex){
ListNode flagIndex = head;
while(flagIndex != aIndex){
flagIndex = flagIndex.next;
aIndex = aIndex.next;
}
return flagIndex;
}
}
return null;
}
}
显然,我们还可以使用哈希表的方法来进行解决,首先是把链表头部节点赋值给一个标记节点记录,然后新建一个集合。通过遍历链表,判断标记节点是否在集合里,如果在集合里就返回标记节点;反之就把标记节点加入到集合里面,然后把标记节点移动到下一个节点。所以根据这个思路就可以写出代码,下面是Python代码部分:
#喷火龙与水箭龟
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
flagNode = head
recordSet = set()
while not flagNode is None:
if (flagNode in recordSet):
return flagNode
else:
recordSet.add(flagNode)
flagNode = flagNode.next
return None
从结果来说java版本的快慢指针方法和python版本的哈希表算法速度都非常不错,应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。