检测链表中的环

  1. 问题描述:给定一个链表,检测该链表中是否存在闭环。要求时间和空间复杂度。

  2. 问题分析:如果存在环,那么我们在遍历链表的时候最终会进入一条无限循环中。我们可以把这视为2个人在操作运动,速度快的最终一定会赶上并且遇上速度慢的,也就是速度快的会比速度慢的多跑n整圈。

  3. 假设a和b俩个物体运动,速度分别为va,vb,要使得运动相差闭环的整圈。需要满足几个条件:
    a. 首先速度需要有快慢我们让vb>=va
    b. 速度慢的物体a要进入环区域才可能有机会。所以有a的移动距离sa>闭环之前的直线距离sl
    c. 在这里我们是通过遍历的方式,所以vb是va的整数倍。这里的移动速度本质上还是遍历,时间复杂度方面,我们这里让vb=2va即可,则有b的运动距离sb = 2sa。b比a多移动的距离sba = sb - sa = sa。
    d. 由以可知sa >= sl,另环的周长为sr,sa是sr的整数倍,这里我们取a的移动距离sa为>= sl的sr的最小整数倍的a和b相遇。那么有sba = sr,sa=sr,sb=2sr(sr >sl)。
    e. 举例,如果sl=2,sr=5,那么sa = 5;如果sl = 10,sr=9,那么sa=18的时候b赶上a。
    f. 时间复杂度为sa。

  4. 代码逻辑

function HasLoop(list,out pmeet)
{
    pmeet  =null
    var head = list.head, p1 = head, p2= head
    var hasLoop = false
    while(true)
    {
        if(null == p2.next || null == p2.next.next) 
            break;
        p1 = p1.next
        p2 = p2.next.next
        if(p1 == p2)
        {
            pmeet  = p1
            hasLoop = true
            break
        }
    }
    return hasLoop
}

. 扩展:求一个闭环链表中的入环点
a. 我们假设在b赶上a的时候a在环内移动距离是s,那么运动起点到环起点距离是sa - s
b. 沿着当前运动方向到环起点的距离是sr - s = sa - s,与以上相同。

function GetLoopNode(list)
{
var pmeet
if(!HasLoop(pmeet)) return null
var p1= list.head,p2 = pmeet
while(p1!= p2)
{
p1= p1.next
p2 = p2.next
}
return p
}

扩展:检测两条链表相交汇合

  1. 将该2链表头尾拼接成一条:当然不一定需要真正意义的拼接,只是采用一定方式使得可以 遍历完全2个链表就可以了。
  2. 然后就采用以上的检测是否闭环和求入环点的方式进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值