考試結束,班級平均分只拿到了年級第二,班主任於是問道:大家都知道世界第一高峰珠穆朗瑪峰,有人知道世界第二高峰是什麼嗎?正當班主任要繼續發話,只聽到角落默默想起來一個聲音:”喬戈裡峰”
前言
2018.11.11號打卡
明天的題目:
https://leetcode-cn.com/problems/sort-array-by-parity/
題目
每天一道leetcode142-尋找連結串列中環的入口
分類:連結串列
中文連結:
https://leetcode-cn.com/problems/linked-list-cycle-ii/
英文連結
https://leetcode.com/problems/linked-list-cycle-ii/
題目詳述
給定一個連結串列,返回連結串列開始入環的第一個節點。 如果連結串列無環,則返回 null。
說明:不允許修改給定的連結串列。
進階:
你是否可以不用額外空間解決此題?
題目詳解
使用額外空間的思路
- 就是使用一個hashmap,去遍歷一遍連結串列,每遍歷一個連結串列,如果不存在這個節點,那麼就插入hashmap,如果存在,說明這個節點已經插入了,那麼這個節點就是重複的節點,為啥重複了,就是環的入口節點了。
程式碼
1/**
2 * Definition for singly-linked list.
3 * class ListNode {
4 * int val;
5 * ListNode next;
6 * ListNode(int x) {
7 * val = x;
8 * next = null;
9 * }
10 * }
11 */
12public class Solution {
13 public ListNode detectCycle(ListNode head) {
14 HashMap<ListNode,Integer> map = new HashMap<>();
15 if(head == null || head.next == null)
16 return null;
17 while(head != null)
18 {
19 if(map.containsKey(head) == false)
20 {
21 map.put(head,1);
22 head = head.next;
23 }else{
24 return head;
25 }
26 }
27 return null;
28 }
29}
複製程式碼
程式碼講解
- 15-22行,hashmap判斷這個節點如果不存在,那麼插入到hashmap裡面;
- 23-24行,hashmap中存在這個節點,那麼就返回這個節點,也就是入口節點
不使用額外空間的思路
- 使用快慢指標,快指標每次走兩步,慢指標每次走一步,如果快慢指標相遇說明有環;
- 有環以後,需要尋找環入口節點,已經找到了一個環的中的節點,利用這個節點,去往下遍歷,由於是環,所以這個節點肯定會和自身相遇,相遇以後,記錄相遇過程中走的步數,就是環的長度
- 知道環的長度以後,然後再利用快慢指標的思想,快指標先走環長度,然後快慢指標再一起走,這樣因為快指標先走了環的長度,當兩者相遇肯定是環的入口節點相遇(為啥呢,因為快慢指標肯定會進入環裡面,而由於快指標先走了環的長度,所以也就是一個週期,所以只要進入環,那麼這兩個指標必然相遇)
程式碼
1/**
2 * Definition for singly-linked list.
3 * class ListNode {
4 * int val;
5 * ListNode next;
6 * ListNode(int x) {
7 * val = x;
8 * next = null;
9 * }
10 * }
11 */
12public class Solution {
13 boolean flag = true;
14 public ListNode detectCycle(ListNode head)
15 {
16 ListNode pHead = head;
17 if(pHead == null || pHead.next == null)
18 return null;
19 ListNode pNode = judgeHasChain(pHead);
20 if(pNode != null)
21 {
22 int lengthChain = 1;
23 ListNode pNodeCopy = pNode.next;
24 while(pNodeCopy != pNode)
25 {
26 lengthChain++;
27 pNodeCopy = pNodeCopy.next;
28 }
29 ListNode fast = pHead;
30 ListNode slow = pHead;
31 int temp = 0;
32 while(temp < lengthChain)
33 {
34 fast = fast.next;
35 temp++;
36 }
37 while(fast != slow)
38 {
39 fast = fast.next;
40 slow = slow.next;
41 }
42 return fast;
43 }
44 return null;
45 }
46 private ListNode judgeHasChain(ListNode pHead)
47 {
48 ListNode fast = pHead.next;
49 ListNode slow = pHead;
50 while(fast != slow)
51 {
52 if(fast != null && fast.next != null)
53 {
54 fast = fast.next;
55 }else{
56 flag = false;
57 break;
58 }
59 if(slow != null && slow.next != null)
60 {
61 slow = slow.next;
62 }else{
63 flag = false;
64 break;
65 }
66 if(fast == slow)
67 {
68 return fast;
69 }else{
70 fast = fast.next;
71 }
72 }
73 if(flag)
74 return fast;
75 return null;
76 }
77}
複製程式碼
程式碼講解
- 46-76 就是判斷連結串列中是否有環,之前有詳細講過 之前的文章連結串列:http://t.cn/EANBcf4
- 19行中,如果連結串列有環,那麼返回的這個節點必然在環中
- 22-28行,利用19行的節點,遍歷計算環的長度
- 32-36行,快指標先走環長度
- 37-41行 快慢指標一起走,相遇就是環的入口節點
結束語
2018.11.11號打卡
作者喬戈裡親歷2019秋招,哈工大計算機本碩,百度准入職java工程師,歡迎大家關注我的微信公眾號:程式設計師喬戈裡,公眾號有3T程式設計資源,以及我和我朋友(准入職百度C++工程師)在秋招期間整理的近200M的面試必考的java與C++面經,並有每天一道leetcode打卡群與技術交流群,歡迎關注。