判断给定的链表中是否有环。如果有环则返回true,否则返回false。 你能给出空间复杂度为o(1)的解法么?
题解1:可以使用快慢指针实现
如果链表中有环,那么快慢指针一定会相遇
解法一:快慢指针法
/**
* 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) {
if(head ==null){
return ;
}
ListNode slow=head;
ListNode fast=head;
while(fast!=null&&fast.next!=null){
slow=slow.next;
fast=fast.next.next;
if(slow==fast){
return true;
}
}
return false;
}
}
题解2:存放到集合中
把节点存放到集合set中,每次存放的时候判断当前节点是否存在,如果存在,说明有环,直接返回true。
解法二:set集合辅助
/**
* 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) {
Set<ListNode> set = new Set<ListNode>();
while(head!=null){
//如果重复出现说明有环
if(set.contains(head)){
return true;
}
set.add(head);
head=head.next;
}
return false;
}
}
题解3:可以通过递归删除节点,如果有环一定会出现head=head.next;
解法三:递归删除
/**
* 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) {
//如果head为空,或者他的next指向为空,直接返回false
if (head == null || head.next == null)
return false;
}
//如果出现head.next = head表示有环
if(head=head.next){
return true;
}
//用于下次删除的节点
ListNode nextNode =head.next;
//当前节点的next指向自己,相当于把它删除
head.next =head;
/然后递归,查看下一个节点
return hasCycle(nextNode);
}