環形連結串列 II
題目描述:給定一個連結串列,返回連結串列開始入環的第一個節點。 如果連結串列無環,則返回 null。
為了表示給定連結串列中的環,我們使用整數 pos 來表示連結串列尾連線到連結串列中的位置(索引從 0 開始)。 如果 pos 是 -1,則在該連結串列中沒有環。注意,pos 僅僅是用於標識環的情況,並不會作為引數傳遞到函式中。
說明:不允許修改給定的連結串列。
進階:
你是否可以使用 O(1) 空間解決此題?
示例說明請見LeetCode官網。
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/probl...
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
解法一:雜湊表
HashSet判斷節點是否重複。
解法二:雙指標法
使用快慢節點,如果有環,則這兩個節點必回相遇。
import java.util.HashSet;
import java.util.Set;
public class LeetCode_142 {
/**
* 雜湊
*
* @param head
* @return
*/
public static ListNode detectCycle(ListNode head) {
if (head == null) {
return null;
}
Set<ListNode> nodes = new HashSet<>();
nodes.add(head);
while (head.next != null) {
// 如果next節點在雜湊表中出現過,說明成環了, 而且next節點肯定是入環點,直接返回
if (nodes.contains(head.next)) {
return head.next;
}
nodes.add(head.next);
head = head.next;
}
return null;
}
/**
* 雙指標法
*
* @param head
* @return
*/
public static ListNode detectCycle2(ListNode head) {
if (head == null) {
return null;
}
ListNode slow = head, fast = head;
while (fast != null) {
slow = slow.next;
if (fast.next != null) {
fast = fast.next.next;
} else {
return null;
}
if (fast == slow) {
ListNode ptr = head;
while (ptr != slow) {
ptr = ptr.next;
slow = slow.next;
}
return ptr;
}
}
return null;
}
public static void main(String[] args) {
ListNode head = new ListNode(3);
head.next = new ListNode(2);
head.next.next = new ListNode(0);
head.next.next.next = new ListNode(-4);
head.next.next.next.next = head.next;
System.out.println(detectCycle(head) == null ? -1 : detectCycle(head).val);
System.out.println(detectCycle2(head) == null ? -1 : detectCycle2(head).val);
}
}
【每日寄語】 人世間不可預料的事情太多了,但是不管怎樣,社會還會照樣執行。一個人不管有多大的成就,在世界萬物中都是非常渺小的,所以要珍惜每一分每一秒。