• 剑指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;
            }
        }
    }
     
  • 相关阅读:
    为什么需要Docker?
    一分钟学会《模板方法模式》
    2018再见|2019你好
    三分钟学会《门面模式》
    策略模式原来这么简单!
    外行人都能看得懂的机器学习,错过了血亏!
    我是如何将博客转成PDF的
    面试前必须知道的MySQL命令【explain】
    count(*)、count(1)和count(列名)的区别
    Linux shell去除字符串中所有空格
  • 原文地址:https://www.cnblogs.com/HuangYJ/p/13619687.html
Copyright © 2020-2023  润新知