最近火爆的新闻大事/seo搜索引擎优化
题目:
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。
思路:
- 1,使用两个指针,快指针与慢指针,慢指针一次走一步,快指针一次走两步。
- 2,两个指针都从A点出发,假设B点是环的入口,如果有环的话,两个指针一定会重合,重合点记为C点。
- 3,从A点到B点的长度记为X,从B点到C点的长度记为Y,当两个指针相遇时,慢指针走过的长度是X+Y,并由此推测快指针走出的长度是2X+2Y,这是因为慢指针走一步,快指针走两步。
- 4,由上图看出,慢指针走过的路线是:AB+BC;而快指针走过的路线是AB+BC+CDB+BC,由此得出等式 2*(AB+BC) = AB+BC+CDB+BC,于是得出AB = CDB。
- 5,据4,如果让两个指针分别从A和C出发,每次走一步,则两个指针的重合点就是入口点。
实现:
- 1,快慢两个指针,判断是否有环,并找到重合点C;
- 2,一个指针从A出发,一个指针从C出发,每次走一步,再次重合的结点就是环的入口。
public ListNode EntryNodeOfLoop(ListNode pHead) {ListNode pre = pHead;ListNode forward = pHead;boolean hasCircle = true;// 判断是否有环,并找到重合点Cwhile(pre != null && forward != null) {pre = pre.next;if (forward.next != null) {forward = forward.next.next;} else {hasCircle = false;break;}// 有环,必须放在这里判断是否有环,不能在循环条件里面判断if (pre == forward) {break;}}// 有环的情况下,两个指针分别从头结点和重合点出发,一次走一步if (hasCircle && pre != null && pre == forward) {pre = pHead;while(pre != forward) {pre = pre.next;forward = forward.next;}return pre;}return null;}