判断链表中是否有环

链表如果有环,称为循环链表;问题在于链表发生环的位置不确定,收尾相连自然很好;大多数情况下环发生在链表内部,如何用最少的空间判断链表的环呢?有一个有意思的思路,定义两个指针,temp和temp2,每次循环temp2走两步,temp走一步,当temp2—>next为null或者temp2—>next—>next为null时即链表无环,当temp==temp2时链表有环。为什么呢?我们选择temp作为temp2的参考系,那么当环存在时,temp2一直在以1的速度在环内追赶temp,有限长度时可以追上。这就是经典的快慢指针法。如何查找入口节点呢?假设temp走过的距离是a+b(假设a处就是入口节点处),链表环的长度是b+c,那么temp2走过的距离是a+2b+c.由于temp2的速度是temp的两倍,有等式a+2b+c=2*(a+b)===》a==c,有了距离相等的条件,此时把temp指针移到原点,那把temp2的移动速度降低到每次移动一个结构体,那么两个指针相遇的地方就是链表环的入口处了。这种算法如果没听说过很难自己想到,所以mark一下。

附上leetcode  c++代码

class Solution {

public:
    bool hasCycle(ListNode *head) {
        ListNode *temp,*temp2;
        temp=head;
        temp2=head;
        bool flag(0);
        if(temp==NULL)
            return 0;
        if(temp->next==NULL)
            return 0;
        while(1)
        {   if(temp2==NULL)
            {flag=0;break;}
            temp=temp->next;
            if(temp2->next==NULL)
            {flag=0;break;}
            temp2=temp2->next->next;
            if(temp2==temp)
            {flag=1;break;}
            
        }
        return flag;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值