版权声明:此文章为许诗宇所写,如需转载,请写下转载文章的地址 https://blog.csdn.net/xushiyu1996818/article/details/82345344
题目及用例
package pid141;
/*环形链表
给定一个链表,判断链表中是否有环。
进阶:
你能否不使用额外空间解决此题?
*/
import pid141.LinkList;
import pid141.LinkList.ListNode;
public class main {
public static void main(String[] args) {
LinkList a=new LinkList(1);
a.addLast(2);
a.addLast(5);
a.printList();
test(a.first);
LinkList b=new LinkList(-5);
b.addLast(0);
b.addLast(-5);
b.first.next.next=b.first;
//b.printList();
test(b.first);
/*LinkList c=new LinkList(1);
c.addLast(2);
c.addLast(2);
c.addLast(1);
c.printList();
test(c.first);*/
/*LinkList c=new LinkList(1);
c.addLast(2);
c.addLast(500);
LinkList d=new LinkList(1);
d.addLast(2);
d.addLast(3);
c.printList();
d.printList();
test(c.first,d.first);*/
}
private static void test(ListNode ito) {
Solution solution = new Solution();
Boolean rtn;
long begin = System.currentTimeMillis();
System.out.println();
//开始时打印数组
rtn=solution.hasCycle(ito);//执行程序
long end = System.currentTimeMillis();
System.out.println(rtn);
//System.out.println(":rtn" );
//System.out.print(rtn);
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
解法1(成功,速度极快,1ms)
不用额外空间,速度o(n)
用双指针,一个在前,另一个在第一个的后面一步
每走一步,将这一步后面的next改为head
这样如果走到的next=head,说明循环
如果为null,不循环
package pid141;
import java.util.ArrayList;
import java.util.List;
import pid141.LinkList;
import pid141.LinkList.*;
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean hasCycle(ListNode head) {
if(head==null||head.next==null){
return false;
}
ListNode now=head.next;
ListNode prev=head;
while(true){
prev.next=head;
if(now.next==null){
return false;
}
if(now.next==head){
return true;
}
prev=now;
now=now.next;
}
}
}
解法2(别人的)
也不错,用双指针,快慢指针,一个一步2格,1个1格
如果循环,那么一定会相遇
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null)
return false;
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast)
return true;
}
return false;
}
解法3(别人的)
与第一种相似,只是将指针指向head改为指向自己
public class Solution {
public boolean hasCycle(ListNode head) {
if(head==null||head.next==null)return false;
if(head.next==head)return true;
ListNode l=head.next;
head.next=head;
boolean isCycle=hasCycle(l);
return isCycle;
}