Leetcode 141:環形連結串列(最詳細的解法!!!)
阿新 • • 發佈:2018-11-09
給定一個連結串列,判斷連結串列中是否有環。
進階:
你能否不使用額外空間解決此題?
解題思路
一個最簡單的做法就是將連結串列反轉,我們看連結串列反轉後有什麼問題,關於連結串列反轉可以看這篇Leetcode 206:反轉連結串列(最詳細解決方案!!!)。
1 -> 2 -> 3 -> 4 -> 5
^ |
| v
___________
我們開始反轉連結串列
1 <- 2 <- 3*<- 4 <- 5 | ^ v | ___________
我們看反轉到3
,現在不會停止,而是會繼續
1 <- 2 -> 3 <- 4 <- 5
| ^
v |
___________
最後就變成了
1 -> 2 -> 3 <- 4 <- 5
| | ^
head v |
___________
此時我們發現又回到了起點處,所以我們最後只要判斷返回的節點是不是head
,就可以判斷是不是有環。
class Solution(object):
def reverseList(self, head):
pre = None
cur = head
while cur != None:
lat = cur.next
cur.next = pre
pre = cur
cur = lat
return pre
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if head != None and head.next != None\
and self.reverseList(head) == head:
return True
return False
這個問題還有一個非常棒的解法,就是使用快慢指標。我們建立兩個指標,一個slow
一個fast
,我們令移動速度關係為
,我們假設環的長度為
的倍數k
,如果此時slow
和fast
都在環內的話,那麼在一定時間內兩者必定可以相遇(使用相對速度很好理解)。
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if head == None:
return False
fast, slow = head, head
while fast.next != None and fast.next.next != None:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
reference:
https://leetcode.com/problems/linked-list-cycle/discuss/44498/Just-reverse-the-list
https://leetcode.com/problems/linked-list-cycle/discuss/44489/O(1)-Space-Solution
我將該問題的其他語言版本新增到了我的GitHub Leetcode
如有問題,希望大家指出!!!