题目描述:环形链表
解题思路:
经典快慢指针思路,声明慢指针slow每次走一步,声明快指针fast每次走两步,只要slow、fastv不为空并且fast.next不是链表尾,一直迭代,直到 slow 和 fast相遇,表示链表有环,否则链表无环。
对于下面这个链表判断其是否有环
(1)、先声明快慢指针
Step1:slow、fast和fast.next 非空,slow步进一步,fast步进两步
Step2:slow != fast 继续迭代,slow步进一步,fast步进两步
重复Step1、Step2 直到 slow == fast
可以看到该链表确实有环,return即可。
参考代码如下:
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode fast, slow;
fast = slow = head;
while(slow!=null && fast!=null && fast.next!=null){
slow = slow.next;
fast = fast.next.next;
if(slow == fast){
return true;
}
}
return false;
}
}
总结: 快慢指针解法的空间复杂度为O(1) ,时间复杂度为O(N)。
题目描述:环形链表 II
解题思路:先参考环形链表解法拿到快慢指针的相遇点,然后另两个指针分别从链表的头结点和相遇结点步进,它们会相遇与环的入口结点。
参考代码如下:
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast,slow;
fast = slow = head;
boolean isCycle = false;
while(slow!=null && fast!=null && fast.next!=null){
slow = slow.next;
fast = fast.next.next;
if(slow == fast){
isCycle = true;
break;
}
}
if(!isCycle){
return null;
}
fast = head;
while(fast != slow){
fast = fast.next;
slow = slow.next;
}
return fast;
}
}