00141 環(huán)形鏈表
題目描述
給定一個(gè)鏈表,判斷鏈表中是否有環(huán)。
實(shí)例 1:
輸入:head = [3,2,0,-4], pos = 1
輸出:true
解釋:鏈表中有一個(gè)環(huán),其尾部連接到第二個(gè)節(jié)點(diǎn)。
示例 2:
輸入:head = [1,2], pos = 0
輸出:true
解釋:鏈表中有一個(gè)環(huán),其尾部連接到第一個(gè)節(jié)點(diǎn)。
示例 3:
輸入:head = [1], pos = -1
輸出:false
解釋:鏈表中沒有環(huán)。
力扣地址
解題報(bào)告
哈希表
本題解由微信公眾號(hào)
小猿刷題提供, 錯(cuò)誤之處, 歡迎指正.
通過檢查一個(gè)結(jié)點(diǎn)此前是否被訪問過來判斷鏈表是否為環(huán)形鏈表。常用的方法是使用哈希表.
/**
* 微信公眾號(hào)"小猿刷題"
* 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) {
Set<ListNode> nodesSeen = new HashSet<>();
while (head != null) {
if (nodesSeen.contains(head)) {
return true;
} else {
nodesSeen.add(head);
}
head = head.next;
}
return false;
}
}
雙指針
本題解由微信公眾號(hào)
小猿刷題提供, 錯(cuò)誤之處, 歡迎指正.
定義兩個(gè)不同速度的快、慢指針遍歷鏈表,慢指針每次移動(dòng)一步,而快指針每次移動(dòng)兩步。如果列表中不存在環(huán),最終快指針將會(huì)最先到達(dá)尾部,此時(shí)我們可以返回 false
/**
* 微信公眾號(hào)"小猿刷題"
* 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) {
// 從鏈表頭部開始
ListNode slow = head;
ListNode fast = head;
while(fast != null && fast.next != null){
// 快慢指針行走
fast = fast.next.next;
slow = slow.next;
// 相遇說明有環(huán)
if(slow == fast){
return true;
}
}
return false;
}
}
00142 環(huán)形鏈表 II
題目描述
給定一個(gè)鏈表,返回鏈表開始入環(huán)的第一個(gè)節(jié)點(diǎn)。 如果鏈表無環(huán),則返回 null。
為了表示給定鏈表中的環(huán),我們使用整數(shù) pos 來表示鏈表尾連接到鏈表中的位置(索引從 0 開始)。 如果 pos 是 -1,則在該鏈表中沒有環(huán)。
說明:不允許修改給定的鏈表。
示例 1:
輸入:head = [3,2,0,-4], pos = 1
輸出:tail connects to node index 1
解釋:鏈表中有一個(gè)環(huán),其尾部連接到第二個(gè)節(jié)點(diǎn)。

示例 2:
輸入:head = [1,2], pos = 0
輸出:tail connects to node index 0
解釋:鏈表中有一個(gè)環(huán),其尾部連接到第一個(gè)節(jié)點(diǎn)。

示例 3:
輸入:head = [1], pos = -1
輸出:no cycle
解釋:鏈表中沒有環(huán)。

進(jìn)階:
- 你是否可以不用額外空間解決此題?
力扣地址
- https://leetcode.com/problems/linked-list-cycle-ii/
- https://leetcode-cn.com/problems/linked-list-cycle-ii/
解題報(bào)告
哈希表
本題解由微信公眾號(hào)
小猿刷題提供, 錯(cuò)誤之處, 歡迎指正.
如果我們用一個(gè) Set 保存已經(jīng)訪問過的節(jié)點(diǎn),我們可以遍歷整個(gè)列表并返回第一個(gè)出現(xiàn)重復(fù)的節(jié)點(diǎn)
/**
* 微信公眾號(hào)"小猿刷題"
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
Set<ListNode> visited = new HashSet<ListNode>();
ListNode node = head;
while (node != null) {
if (visited.contains(node)) {
return node;
}
visited.add(node);
node = node.next;
}
return null;
}
}
雙指針
本題解由微信公眾號(hào)
小猿刷題提供, 錯(cuò)誤之處, 歡迎指正.
圖解快慢指針判斷環(huán)&環(huán)入口算法.
/**
* 微信公眾號(hào)"小猿刷題"
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next; // 快指針移動(dòng)2位
slow = slow.next; // 慢指針移動(dòng)1位
// 快慢指針的處理只能判斷是否有環(huán),并不能判斷出在哪里出現(xiàn)的環(huán)(相遇說明有環(huán))
if(fast == slow){
fast = head;
// 重置快指針, 然后各自都移動(dòng)1位,再次相遇的地方就是環(huán)入口
while(slow != fast){
fast = fast.next;
slow = slow.next;
}
return fast;
}
}
return null;
}
}