我是靠谱客的博主 迷路冬天,最近开发中收集的这篇文章主要介绍环形链表(快慢指针)环形链表(快慢指针),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 环形链表(快慢指针)
    • 题目
    • 思路
    • 代码
    • leetcode展示

环形链表(快慢指针)

题目

在leetcode上有两道关于环形链表的题,分别是:

  • 给定一个链表,判断链表中是否有环。
  • 给定一个链表,返回链表开始入环的第一个节点。

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190906171917858.png
如上图所示,第一题你需要返回true,第二道题你需要告诉人家入环点为2。

思路

我的第一反应是哈希表,这样的时间复杂度可以控制在O(n),但是空间复杂度也是O(n)。

具体的做法就是每遍历一个节点,就把它放在哈希表中去,如果遍历到NULL节点就是没有环,如果遍历到第一次在哈希表中存在的节点,那么就是有环,并且是第一个入环点。

为了优化空间复杂度,我想了许久,也看了点资料。

快慢指针法

定义两个指针,分别为slow和fast,一快一慢。起始点都是HEAD节点,以上图为例,就是节点3。

两个指针同时开始移动,fast指针每次移动两个位置,(3-> 0 -> 2)、slow指针每次移动一个位置,(3-> 2 -> 0)。

fast指针每走一步就拉slow指针1个位置,

假设开始节点HEAD距离入环点距离为N,当slow到达入环点的时候,其实快指针已经在环里面走了N的距离了,如果环的长度为K,那么以fast指针的视角来看,可以理解为slow指针在它前面K-N个位置(假设环足够大)。因为fast指针每走一步就拉slow指针1个位置,所以经过K-N个位置之后(慢指针的速度,快指针已经走了2(K-N)),快慢指针就会相遇。

上面的原理就可以解开问题一。

相遇之后fast和slow指针的位置为入环点后(K-N)个位置,也就是说他们再走N个位置将会到达入环点。而HEAD到达入环点的距离也正好是N,我们选取fast点把它指向HEAD节点,然后fast和slow同时开始移动(注意,fast和slow每次都移动一个位置)。经过N步之后,他们会同时到达入环点。

上面的原理就可以解开问题二。

用这种方式解答这道题时间复杂度为O(n),空间复杂度为O(1)。

代码

问题一

public class Solution {
    public boolean hasCycle(ListNode head) {
      if (head == null || head.next == null) {
            return false;
        }

        ListNode slow = head;
        ListNode fast = head;

        boolean first = true;

        while (first || slow != fast) {

            if (fast == null || fast.next == null) {
                return false;
            }
            fast = fast.next.next;
            slow = slow.next;
            first = false;
        }


        return true;
    }
}

问题二

public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null || head.next == null) {
            return null;
        }

        ListNode slow = head;
        ListNode fast = head;

        boolean first = true;

        while (first || slow != fast) {

            if (fast == null || fast.next == null) {
                return null;
            }
            fast = fast.next.next;
            slow = slow.next;
            first = false;
        }

        fast = head;

        while (fast != slow) {
            fast = fast.next;
            slow = slow.next;
        }

        return fast;
    }
}

leetcode展示

在这里插入图片描述

最后

以上就是迷路冬天为你收集整理的环形链表(快慢指针)环形链表(快慢指针)的全部内容,希望文章能够帮你解决环形链表(快慢指针)环形链表(快慢指针)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(83)

评论列表共有 0 条评论

立即
投稿
返回
顶部