考试结束,班级平均分只拿到了年级第二,班主任于是问道:大家都知道世界第一高峰珠穆朗玛峰,有人知道世界第二高峰是什么吗?正当班主任要继续发话,只听到角落默默想起来一个声音:”乔戈里峰”
前言
2018.11.11号打卡明天的题目:
题目
每天一道leetcode142-寻找链表中环的入口
题目详述
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 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 就是判断链表中是否有环,之前有详细讲过 之前的文章链表:每天一道leetcode141-环形链表
19行中,如果链表有环,那么返回的这个节点必然在环中
22-28行,利用19行的节点,遍历计算环的长度
32-36行,快指针先走环长度
37-41行 快慢指针一起走,相遇就是环的入口节点
结束语
2018.11.11号打卡
作者乔戈里亲历2019秋招,哈工大计算机本硕,百度准入职java工程师,欢迎大家关注我的微信公众号:程序员乔戈里,公众号有3T编程资源,以及我和我朋友(准入职百度C++工程师)在秋招期间整理的近200M的面试必考的java与C++面经,并有每天一道leetcode打卡群与技术交流群,欢迎关注。