环链表、相交链表的问题

有一种直接快速的方法,在每个链表节点处挂一个标志,表示是否访问过,如果在遍历过程中找到已置标志位的节点,则该节点就是环入口点,遍历结束没找到说明不带环。
经典的做法是用快慢指针法。快指针步进2,慢指针步进1,如有环必然相遇,无环时会有指针走到NULL。
这样的复杂度为o(n)。理由是:假定环长为r,在慢指针入环时,快指针在它前面k步处,那么快指针必在第(r-k)步时与慢指针会于离环起点(r-k)步处。总共的步进数为a(环起点到链表起点的距离) + (r - k) < a + r = n。
如何找到入口点呢?让慢指针步进k步即可,但k不可知。注意到总步进次数s有:2*s = s + nr,a + (r - k) = s,即重合处慢指针再步进a步将回到环入口处,要步进a步,可让快指针回到链表头部,变慢(每次步进1),这样两个指针重合处即是环入口处。
扩展问题:两个单链表是否有交点。
方法一:将一链表首尾相接,判断另一链表是否有环,这样可以顺带求出相交处。
方法二:直接判断最后一个元素是否一样。

方法三:最直观的用经典的在线LCA算法,如果父亲不同,短链表指针不动,长链表指针后移,这样还可以找到他们的交点即他们的最近公共祖先。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值