定義一個集合用來存放結點的引用,並將其初始化爲空,從鏈表的頭結點開始向後遍歷,每遍歷到一個結點就判斷集合中是否有這個結點的引用,若是沒有,說明這個結點是第一次訪問,尚未造成環,那麼將這個結點的引用添加到集合中去。若是在集合中找到了一樣的結點,那麼說明這個結點已經被訪問過了,因而就造成了環。這種方法的時間複雜度爲O(n),空間複雜度也爲O(n)。node
定義兩個指針fast(快)與slow(慢),兩者的初始值都指向鏈表頭,指針slow每次前進一步,指針fast每次前進兩步,兩個指針同時向前移動,快指針每移動一次都要跟慢指針比較,若是快指針等於慢指針,就證實這個鏈表是帶環的鏈表。app
若是單鏈表有環,那麼按照上述方法二的思路,當走得快的指針fast與走得慢的指針slow相遇時,slow 指針確定沒有遍歷完鏈表,而fast指針己經在環內循環了n圈 (n>=1)。若是slow 指針走了s步,則fast指針走了2s步,fast步數還等於s加上在環上多轉的n圈,假設環長爲r,則知足以下關係表達式:
2s = s +or
由此能夠獲得 : s=nr
設整個鏈表長爲L,入口環與相遇點距離爲x,起點到環入口點的距離爲a。則知足以下關係表達式:
a+x=nr
a+x=(n-1)r+r=(n-l)r+L-a
a=(n-l)r+(L-ax)
(L-a-x)爲相遇點到環入口點的距離,從鏈表頭到環入口點的距離=(n-l)*環長+相遇點到環入口 點的長度,因而從鏈表頭與相遇點分別設一個指針,每次各走一步,兩個指針一定相遇,且相遇第一點爲環入口點。將相遇點指針的前一個節點的next域設成None便可解環。oop
# -*-coding:utf-8-*- """ @Author : 圖南 @Software: PyCharm @Time : 2019/9/6 15:28 """ class Node: def __init__(self, data=None, next=None): self.data = data self.next = next # 構造單鏈表 def con_link(s, k): head = Node() cur = head nums = list(map(int, s.split(' '))) k = int(k) for num in nums: node = Node(num) cur.next = node cur = node tmp = head if k != 0: for i in range(k): tmp = tmp.next cur.next = tmp return head # 打印單鏈表(用到方法一中的思想) def print_link(head): if head is None or head.next is None: return None flag = [] cur = head.next while cur: if cur not in flag: flag.append(cur) print(cur.data, end=' ') cur = cur.next else: print(cur.data, end=' ') break print() # 判斷鏈表中是否有環 def isLoop(head): if head is None or head.next is None: return None fast = head.next slow = head.next while True: try: fast = fast.next.next slow = slow.next except Exception: print("該鏈表中沒有環!") print_link(head) return False, head if fast == slow: print("該鏈表中有環!") print_link(head) return True, fast # 查找環的入點口,並解環 def findLoopNode(head, fast): cur = head.next pre = None while cur != fast: pre = fast cur = cur.next fast = fast.next print(cur.data) # 解環並打印鏈表 pre.next = None print_link(head) if __name__ == '__main__': nums = input('鏈表:') # 輸入環的入口點,若爲0則鏈表中無環 k = input('環的入點口:') head = con_link(nums, k) f, fast = isLoop(head) if f: findLoopNode(head, fast)
帶環單鏈表
無環單鏈表
3d