题目:怎样才能检测到链表中存在环。
没有任何条件限制:
方案:使用标记法:将访问过的元素进行标记(通过修改链表的结构),如果遍历玩链表还没有碰见标记的元素,则说明没有环,反之则有;O(N)时间复杂度。
数据位于只读存储区,不能修改:
方案:空间换时间:申请一个N个元素大小的内存空间,用哈希表将所有的元素保存起来,看后面的元素有没有重复的,若有,则存在环;没有则不存在。时间复杂度为O(N),空间复杂度为O(N)。
没有足够的空间:
方案一:使用两个指针,第一个指针指向第一个数据,第二个指针依次遍历后面的数据,如果没有;则第一个指针向后移一个,第二个指针再从第三个元素一次向后查找遍历....看是否有相等的数据,若有,则存在环;否则,不存在环。但是此种算法效率实在低下,O(N*N),泛善可陈,丢掉吧。
方案二(推荐):还是设置两个指针。由于链表的长度是任意的,所以先看一种特殊的情况:就是有三个元素,其实只有两个值,第二个元素的下一个就是第一个元素。如果不存在则进行下一步判断,第一个指针走一步,第二个指针走两步,这样如果立案表里有环,则这两个指针将深陷此环而永不复出,那么一个走一步,另一个走两步,总有一天会相遇,如果存在值相等,则说明有环,否则如果有一个指针走到了链表的尽头,等于NULL,则说明链表中五环。时间复杂度为O(N),空间复杂度为0。详细图如下:
但是这些方案也有局限性,前提是链表里没有重复数据,否则不好使,将会把重复的数据判断是有环存在。
所以如果该链表可以修改我们可以采取标记法来判断就可以处理重复的数据了!时间复杂度O(N)。
如果不能修改但是可以申请空间,那么我们就可以用哈希表的结构照样采用标记法来判断是否有环。时间复杂度为O(N)。
如果既不能修改也不能申请空间,除了设置两个指针以外,我想我们可以比较地址,但是效率较低O(N*N)!