快慢指针法~!

23 篇文章 0 订阅

题目:

      给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
     链表的结构如下图:

struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};

     这个题目简洁明了,完全不做作。一看这个题目有两个思路:

(1)标记法

          非常简直直接的思路,就是记录一下走过的路径,如果碰到已经走过的路径,那么就是说碰到了环路的就说明找到了环路的入口,

程序:

    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        set<ListNode*> map;
        while(pHead!=NULL){
            auto temp=map.insert(pHead);
            if(temp.second==false)
                return pHead;
            pHead=pHead->next;
        }
        return NULL;
    }

(2)快慢指针法

        这个思路就不是那么的直接了,就是一开始设置两个指针,一个慢指针,一个快指针。快指针每次走两步,慢指针每次走一步,如果有环路,那么快慢指针一定会相遇,因为会进入环路,会一直在环路里面你追我赶,一定会相遇的。

       让相遇的时候,设置两个慢指针,一个从表头,一个从相遇的点继续出发,每次走一步,那么相遇的的地方就是环的入口。

     论证:(1)有环路,就一定会相遇。

                (2)假设表头到环入口的长度为a  ,环入口到相遇点为b ,相遇点到环入口长度为c

                   当相遇的时候,快指针=a+(b+c)*k+b,期中k是走了k圈,k>=1;

                                            蛮指针=a+b;

                                           由于蛮指针走的比快指针慢1/2, 所以有:(a+b)*2=a+(b+c)*k +b

                                           所以:a=(k-1)*(b+c)+c , 所以说a到环入口的长度是 相遇点到环入口的长度加上环周长的整数倍

所以两个指针同时从环起点和相遇点开始跑,那么久一定可以在环的入口相遇的。

                

代码:

    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        ListNode* Fast=pHead;
        ListNode* Slow=pHead;
        while(Fast!=NULL){
            //相遇点 
            Slow=Slow->next;
            Fast=Fast->next;
            if(Fast==NULL)
                return NULL;
            Fast=Fast->next;
            
            if(Fast==Slow){
                break;
            }
        }
        if(Fast==NULL)
            return NULL;
        //从开始和相遇点同时出发
        Fast=pHead;
        while(Fast!=Slow){
           Fast=Fast->next;
           Slow=Slow->next;
        }
        return Slow;
    }

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值