判断单向链表中是否有环并确定开始位置

    第一个问题,判断单向链表中是否有环。网上搜到的方法,步长法,两个指针p1和p2,分别以步长1和2开始遍历链表,如果p2追上了p1,则说明存在环路。

    p2每次走2步,p1每次走1步,如果没有环路的话,p2肯定会先到达终点,即p2->next=null。

   

    1(h)->2->3(s)->4->...->m->...->n-1->n(e)->3

假设链表是这样地,环路是从第3个节点开始的。假设p1,p2相遇于m节点。

p1走的距离=[h,s] + [s,m] + x[s,e] x表示p1走了x圈, x>=0

p2走的距离=2([h,s] + [s,m] + x[s,e])

 

p1,p2相遇肯定是在[s,e]这个区间,他们的位移相同,不过p2可能比p1多跑了z圈,z>=1。

2([h,s] + [s,m] + x[s,e])- ([h,s] + [s,m] + x[s,e]) = z[s,e] 即  [h,s] + [s,m] + x[s,e] =  z[s,e] 即 [h,s] + [s,m] = (z-x)[s,e]。存在使这个等式成立的数,比如 2 + 4 = (1 - 0) * 6。

 

(可是总觉得哪里不对劲呢?)

 

[占位待续]

 

 

    还有没有别的方法呢?如果存在环路的话,则有两个节点的next指针,指向同一个地址。指针p从头节点开始遍历,用一个数据结构来记录每个节点的next地址的值,如果p->next=null,走完了整个链表,说明没有环路。否则一定会有某个节点的next值已经被记录过了,这个next指向的节点就是环路的开始。

    现在的问题是,用什么样的数据结构来保存next值,并且可以实现快速查找。因为不知道链表节点的数目,所以这个数据结构要能够动态分配和增长。。。啊,好像又是链表比较合适,原始链表的每个节点的next值,组成一个新的链表,记为LL,并且指针p每移动一步,都需要从头遍历LL,查找是否出现过p->next值。。。哇,好麻烦。。其实我一开始想用hash的,但是这个地址又不是ASCII码。。。。可以先分配固定长度,比如256个元素的数组,然后设计一个hash函数,将p->next值映射到数组,冲突解决嘛,链地址法。。。OMG,也好复杂哦。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值