剑指55.链表中环的入口结点

题目描述

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
 

思路

思路1:使用HashMap。用Map保存链表中每个节点出现的次数,第一次出现2次的节点就是我们所要找的环的入口结点,如果没有找到,返回null。

 

思路2:快慢指针。将该问题分解为3个步骤:

  • 1)确定链表是否有环:通过两个快慢指针确定
  • 2)得到环中结点的数目n:指针走1圈,边走边计数,再次回到这个结点时便得到环中的结点数目。
  • 3)找到环路的入口:从头结点开始,通过两个相差为n的快慢指针来得到(即转化为寻找链表中倒数第n个结点)

 

解法1

import java.util.*;
public class Solution {
    public ListNode EntryNodeOfLoop(ListNode pHead) {
        Map<ListNode,Integer> map = new HashMap<>();
        ListNode cur = pHead;
        while (cur != null){
            map.put(cur,map.getOrDefault(cur,0) + 1);
            if (map.get(cur) == 2){
                return cur;
            }
            cur = cur.next;
        }
        return null;
    }
}

 

☆解法2

public class Solution {
    public ListNode EntryNodeOfLoop(ListNode pHead) {
        if (pHead == null) return null;
        ListNode fast = pHead;
        ListNode slow = pHead;
        boolean flag = false;
        // 1.判断链表中是否有环
        while (fast != null && fast.next != null){ // 条件很重要!! 如果链表没有环,且结点数是偶数或奇数
            slow = slow.next;
            fast = fast.next.next;
            if (fast == slow){
                flag = true;
                break;
            }
        }
        if (!flag){
            return null;
        }else{
            // 2.得到环中结点的数目
            int count = 1; // 统计环中结点数目。 应该初始化为1 ,因为先走了1步
            fast = fast.next;
            while (fast != slow){
                fast = fast.next;
                count++;
            }
            // 3.找到环中的入口结点
            fast = slow = pHead;
            for (int i = 0; i < count; i++) {
                fast = fast.next;
            }
            while (fast != slow){
                fast = fast.next;
                slow = slow.next;
            }
            return fast;
        }
    }
}

 

 

 
posted @ 2020-09-05 22:24  不学无墅_NKer  阅读(158)  评论(0编辑  收藏  举报