链表中环的问题

Leetcode 141. Linked List Cycle 链表是否有环

两个指针一个一步一步的走,一个两步两步的走,相遇则就是有环

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode temp1 = head,temp2 = head;
        while(temp1 != null){
            temp2 = temp2.next;
            if(temp1.next == null) return false;
            temp1 = temp1.next.next;
            if(temp1 == temp2) return true;
        }
        return false;
    }
}


走两步的temp2和走一步temp1的两个指针相遇了之后,重新定义temp = head,temp走一步,temp1走一步,t他们两个相遇的时候就是环的入口,证明如下:
Leetcode 142. Linked List Cycle II 找到环的入口

设temp1和temp2相遇一共走了t次,那么temp1走过的路程为t,temp2走过的路程为2t,设换长为l,则有2t-t = nl,即t= nl。设从链表头节点到链表环入口节点的长度为a,从头节点到相遇的节点的距离为d,则有t = a+d +ml(可能temp1也绕环了),根据上面的t=nl可知a+d = l(a+d只能是一倍的环长)


public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode temp1 = head,temp2 = head;
        while(temp1 != null && temp1 .next != null){
            temp1 = temp1.next.next;
            temp2 = temp2.next;
            if(temp1 == temp2){
              temp1 = head;
              while(temp1 != temp2){
                  temp1 = temp1.next;
                  temp2 = temp2.next;
              }
              return temp1;
            }
        }
        return null;
    }
}


内容概要:文章基于4A架构(业务架构、应用架构、数据架构、技术架构),对SAP的成本中心和利润中心进行了详细对比分析。业务架构上,成本中心是成本控制的责任单元,负责成本归集与控制,而利润中心是利润创造的独立实体,负责收入、成本和利润的核算。应用架构方面,两者都依托于SAP的CO模块,但功能有所区分,如成本中心侧重于成本要素归集和预算管理,利润中心则关注内部交易核算和获利能力分析。数据架构中,成本中心与利润中心存在多对一的关系,交易数据通过成本归集、分摊和利润计算流程联动。技术架构依赖SAP S/4HANA的内存计算和ABAP技术,支持实时核算与跨系统集成。总结来看,成本中心和利润中心在4A架构下相互关联,共同为企业提供精细化管理和决策支持。 适合人群:从事企业财务管理、成本控制或利润核算的专业人员,以及对SAP系统有一定了解的企业信息化管理人员。 使用场景及目标:①帮助企业理解成本中心和利润中心在4A架构下的运作机制;②指导企业在实施SAP系统时合理配置成本中心和利润中心,优化业务流程;③提升企业对成本和利润的精细化管理水平,支持业务决策。 其他说明:文章不仅阐述了理论概念,还提供了具体的应用场景和技术实现方式,有助于读者全面理解并应用于实际工作中。
<think>好的,我现在要解决用户的问题:如何在链表中找到环的入口节点。根据用户提供的引用内容,我需要结合已有的信息来整理出一个清晰的回答。首先,用户提到了快慢指针法,这应该是关键。 首先,我需要回顾一下快慢指针法的基本步骤。根据引用[1]和[2],算法分为两个阶段:判断是否有环,然后找到入口。当快慢指针相遇时,说明存在环。然后,将快指针(或者另一个指针)移回头部,以相同速度移动,直到相遇点即为入口。 接下来,我需要理解这个算法背后的数学原理。引用[3]和[4]提到,假设链表头到入口的距离是a,入口到相遇点的距离是b,相遇点到入口的距离是c。快指针走的路程是a + n(b+c) + b,而慢指针是a + b。根据快指针是慢指针速度的两倍,可以得到等式:a + n(b+c) + b = 2(a + b),化简后得到a = (n-1)(b+c) + c。这说明a等于c加上n-1圈环的长度。因此,当两个指针分别从头节点和相遇点出发,以相同速度前进时,它们会在入口相遇。 然后,我需要考虑如何将这个逻辑转化为代码。根据引用[4]和[5]中的示例代码,实现步骤大致如下: 1. 初始化快慢指针,都指向头节点。 2. 快指针每次移动两步,慢指针每次移动一步,直到相遇或快指针到达链表末尾(无环)。 3. 相遇后,重置快指针到头部,然后快慢指针以每次一步移动,再次相遇点即为入口。 需要注意的是边界条件,比如链表为空或者只有一个节点的情况。此外,要确保快指针在移动时不会访问空指针的next,因此在循环条件中需要检查fast和fast->next是否为null。 现在,我需要用中文将这些步骤清晰地表达出来,并确保代码部分正确无误。同时,根据用户提供的引用,可能还需要对比哈希表的方法,说明快慢指针法的优势,比如空间复杂度为O(1)。 最后,生成相关问题,如算法的时间复杂度、证明过程、其他方法等,以帮助用户深入理解。</think>### 链表环的入口节点查找方法 #### 核心算法:快慢指针法(Floyd算法) **实现步骤**: 1. **判断环的存在性** 初始化快指针$fast$和慢指针$slow$,均指向链表头部。快指针每次移动两步,慢指针每次移动一步。若两指针相遇,则说明链表存在环。 2. **定位入口节点** 当快慢指针相遇后,将快指针重新指向链表头部。随后,快慢指针以相同速度(每次一步)同步移动。当它们再次相遇时,所在位置即为环的入口节点。 #### 数学原理 设链表头到环入口的距离为$a$,环入口到相遇点的距离为$b$,相遇点到环入口的距离为$c$(环总长$L=b+c$)。 - **快指针路程**: $a + nL + b$($n$为快指针在环内绕行的圈数) - **慢指针路程**: $a + b$ 根据速度关系$v_{fast}=2v_{slow}$,可得: $$a + nL + b = 2(a + b) \implies a = (n-1)L + c$$ 这表明$a$等于$c$加上若干倍环长。因此从头指针和相遇点同步移动时,最终会在环入口相遇[^4]。 #### 代码实现(Python) ```python class ListNode: def __init__(self, x): self.val = x self.next = None def detectCycle(head: ListNode) -> ListNode: fast, slow = head, head # 第一阶段:检测环 while fast and fast.next: fast = fast.next.next slow = slow.next if fast == slow: # 相遇说明有环 # 第二阶段:定位入口 fast = head while fast != slow: fast = fast.next slow = slow.next return fast return None # 无环 ``` #### 对比哈希法 - **快慢指针法**:时间复杂度$O(n)$,空间复杂度$O(1)$,无需额外存储。 - **哈希法**:记录访问过的节点,第一个重复节点即入口,时间复杂度$O(n)$,空间复杂度$O(n)$[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值