【141】题目(难度:简单):
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
代码思想:
设置两个指针,一个每次走一步的慢指针和一个每次走两步的快指针。
- 如果不含有环,跑得快的那个指针最终会遇到 null,说明链表不含环
- 如果含有环,快指针会超慢指针一圈,和慢指针相遇,说明链表含有环。
代码实现:
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null || head.next.next == null) return false;
ListNode slow = head.next;
ListNode fast = head.next.next;
while (slow != fast) {
if (fast.next == null || fast.next.next == null) {
return false;
}
slow = slow.next;
fast = fast.next.next;
}
return true;
}
运行结果:
算法分析:
时间复杂度O(n),额外空间复杂度O(1)
【142】题目(难度:中等):
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
代码思想:
在上一题的基础上,将fast重写索引至head,再依次遍历fast和slow,当两者再次相遇时,即为环的第一个节点。(此结论记住即可)
代码实现:
public ListNode detectCycle(ListNode head){
if (head == null || head.next == null || head.next.next == null) return null;
ListNode slow = head.next;
ListNode fast = head.next.next;
while (slow != fast) {
if (fast.next == null || fast.next.next == null) {
return null;
}
slow = slow.next;
fast = fast.next.next;
}
fast = head;
while(slow!=fast){
slow=slow.next;
fast=fast.next;
}
return slow;
}
运行结果:
算法分析:
时间复杂度O(n),额外空间复杂度O(1)