LeetCode #141 題目描述:
給定一個鏈表,判斷鏈表中是否有環。
如果鏈表中存在環,則返回 true 。 否則,返回 false 。
進階:你能用 O(1)(即,常量)內存解決此問題嗎?
示例 1:
example1
輸入:head = [3,2,0,-4], pos = 1
輸出:true
解釋:鏈表中有一個環,其尾部連接到第二個節點。
示例 2:
example2
輸入:head = [1,2], pos = 0
輸出:true
解釋:鏈表中有一個環,其尾部連接到第一個節點。
示例 3:
example3
輸入:head = [1], pos = -1
輸出:false
解釋:鏈表中沒有環。
提示:
鏈表中節點的數目範圍是 [0, 1e4]
-1e5 <= Node.val <= 1e5
pos 爲 -1 或者鏈表中的一個 有效索引 。
LeetCode #141 解題思路:
這道題可以使用兩種方法來解決:
方法一:【哈希表】
我們遍歷鏈表中的每一個節點,將當前節點添加到哈希表中,然後考慮下一個節點,如果下一個節點存在於哈希表中,說明存在環;否則如果抵達了空節點 null 還沒有找到環的話,則說明不存在環。
方法二:【快慢指針】
這種方法也被稱爲 Floyd 判圈算法。首先我們定義兩個指針:快指針和慢指針。將快指針和慢指針都指向鏈表開頭,然後讓它們同時往鏈表尾部移動。此時,如果鏈表中不存在環,那麼快指針遲早會到達鏈表末尾,此時可以返回 false。但是如果鏈表中存在環,則快指針就會在環內繞圈,而慢指針不會進入重複區域,因此最終一定會追上快指針。此時可以返回 true。
本題使用的是方法二,快慢指針
//leetcode submit region begin(Prohibit modification and deletion)
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
if(head==null){
return false;
}
ListNode fastP = head;
ListNode slowP = head;
//如果有環一定相遇在環內
while(fastP!=null && fastP.next!=null){
fastP = fastP.next.next;
slowP = slowP.next;
if(fastP == slowP){
return true;
}
}
return false;
}
}
//leetcode submit region end(Prohibit modification and deletion)