LeetCode - Medium - 142

【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】

**开源地址:https://docs.qq.com/doc/DSmxTbFJ1cmN1R2dB **

Example 2:

Input: head = [1,2], pos = 0

Output: tail connects to node index 0

Explanation: There is a cycle in the linked list, where tail connects to the first node.

Example 3:

Input: head = [1], pos = -1

Output: no cycle

Explanation: There is no cycle in the linked list.

Constraints:

  • The number of the nodes in the list is in the range [0, 104].

  • -10⁵ <= Node.val <= 10⁵

  • pos is -1 or a valid index in the linked-list.

Analysis


方法一:《剑指Offer》No.23的解法

  1. 查 - 查看是否存在环,有环的得出快慢指针相遇时所处在节点,进行下一步,没环的直接返回。这用到快慢双指针算法,具体内容可查看LeetCode - Easy - 141. Linked List Cycle。

  2. 量 - 测量环节点个数n。

  3. 走 - 双指针指向头指针,一指针先走n步,然后两指针齐步走,两指针相等的位置,则环的入口点。


方法二:LeetCode优秀的回答

When fast and slow meet at point p, the length they have run are ‘a+2b+c’ and ‘a+b’.

Since the fast is 2 times faster than the slow. So a+2b+c == 2(a+b), then we get ‘a==c’.

So when another slow2 pointer run from head to ‘q’, at the same time, previous slow pointer will run from ‘p’ to ‘q’, so they meet at the pointer ‘q’ together.

Submission


import com.lun.util.SinglyLinkedList.ListNode;

public class LinkedListCycleII {

//方法一:《剑指Offer》的解法

public ListNode detectCycle1(ListNode head) {

ListNode collision = hasCycle(head);

if (collision != null) {

int cycleLength = count(collision);

ListNode p1 = head;

ListNode p2 = head;

while (cycleLength-- > 0) {

p2 = p2.next;

}

while (p1 != p2) {

p1 = p1.next;

p2 = p2.next;

}

return p1;

}

return null;

}

// 判断是否存在环

private ListNode hasCycle(ListNode head) {

ListNode walker = head;

ListNode runner = head;

while (runner != null && runner.next != null) {

walker = walker.next;

runner = runner.next.next;

if (walker == runner)

return walker;

}

return null;

}

// 计算环有多少节点

private int count(ListNode p1) {

int count = 1;

ListNode p = p1.next;

while (p != p1) {

count++;

p = p.next;

}

return count;

}

//方法二:leetcode优秀回答

public ListNode detectCycle2(ListNode head) {

ListNode fast = head, slow = head;

while (fast != null && fast.next != null) {

fast = fast.next.next;

slow = slow.next;

if (fast == slow) {

ListNode slow2 = head;

while (slow != slow2) {

slow2 = slow2.next;

slow = slow.next;

}

return slow;

}

}

return null;

}

}

Test


import static org.junit.Assert.*;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值