算法系列-力扣141-链表中环的检测(含数学证明)

题目说明

你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。

示意图:

方法一

思路:

如果链表中没有环的话我们遍历完整个链表每个节点只会被访问一次,相反如果链表中有环一次会存在某个节点重复访问的情况。

因此我们用一个hash表记录访问过的链表,当有重复时就代表链表中存在环。

复制代码
    public boolean hasCycle(ListNode head) {
        /*
         * 用一个哈希表记录访问过的节点,当链表节点重复时代表当前的链中存在环
         */
        if(head==null){
            return false;
        }
        ListNode p = head;
        Set<ListNode> set = new HashSet<>();
        while(p!=null){
            if(!set.add(p)){
                return true;
            }
            p = p.next;
        }
        return false;
    }

算法分析

我们最多循环完整个链表就可以知道链表中是否存在环,因此该算法的时间复杂度为O(n)

空间复杂度,我们需要用哈希表来存储访问过的节点,同样的也是最多储存n个节点,空间复杂度为O(n)

方法二

思路:

1.声明一快一慢两个指针,慢指针每次移动一步,快指针每次移动两步。如果链表中有环,快指针和慢指针一定会在k步内相遇。

证明:
证明慢指针进入环一圈内会和快指针相遇 设环的长度为C,
假设当慢指针进入环的入口时快指针的位置为A, 设环入口的位置为0
则A的取值范围为[0,C-1] 假设慢指针移动k步后和快指针相遇,慢指针跑出距离0+k,快指针跑出距离2k+A
此时快指针比慢指针要绕环多跑n圈(从慢指针入环后开始计数) 我们有 2k+A - (k+0) = nC 简化得 k + A = nC
当n取值为1时,可得出k一定有解,且k的取值范围为 [0,C-1] 特殊情况:当A的值为0时,此时慢指针刚进入环就和快指针相遇此时k为0,此时n取值0

示意图:

复制代码
import java.util.HashSet;

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        /*
         * 用快慢两个指针访问链表
         * 快指针每次前进两步,慢指针每次前进一步
         * 当链表中存在环时快指针一定会在某个时刻追上慢指针
         */
        if(head==null||head.next==null){
            return false;
        }
        ListNode slow = head;
        ListNode fast = head;
 
        do {
            if(fast==null||fast.next==null){
                return false;
            }
            slow=slow.next;
            fast=fast.next.next;
        } while(fast!=slow);
        return true;
    }
}

算法分析

如果链表中没有环我们最多循环完整个链表就可以知道链表中是否存在环,存在环的情况下快慢指针一定会在环的第一圈内相遇,因此该算法的时间复杂度为O(n)

我们值需要常量的空间来存储额外的变量,空间复杂度为O(1)

相关推荐
We་ct8 分钟前
LeetCode 73. 矩阵置零:原地算法实现与优化解析
前端·算法·leetcode·矩阵·typescript
天赐学c语言8 分钟前
2.1 - 反转字符串中的单词 && 每个进程的内存里包含什么
c++·算法·leecode
程序员泠零澪回家种桔子11 分钟前
OpenManus开源自主规划智能体解析
人工智能·后端·算法
请注意这个女生叫小美13 分钟前
C语言 实例20 25
c语言·开发语言·算法
好学且牛逼的马14 分钟前
【Hot100|22-LeetCode 206. 反转链表 - 完整解法详解】
算法·leetcode·矩阵
hans汉斯16 分钟前
国产生成式人工智能解决物理问题能力研究——以“智谱AI”、“讯飞星火认知大模型”、“天工”、“360智脑”、“文心一言”为例
大数据·人工智能·算法·aigc·文心一言·汉斯出版社·天工
v_for_van20 分钟前
力扣刷题记录3(无算法背景,纯C语言)
c语言·算法·leetcode
ValhallaCoder23 分钟前
hot100-矩阵
数据结构·python·算法·矩阵
散峰而望24 分钟前
【基础算法】穷举的艺术:在可能性森林中寻找答案
开发语言·数据结构·c++·算法·随机森林·github·动态规划
心.c26 分钟前
Vue3+Node.js实现文件上传分片上传和断点续传【详细教程】
前端·javascript·vue.js·算法·node.js·哈希算法