判断链表是否存在环
题目
链表有环解释为链表的某个节点的next域指向链表中它的前一个节点,这样就行成了一个环形结构
例如一个链表:head–>0–>1->2–>3–>4–>5->4就是一个环形的链表
思路
方法1:HashSet实现
利用hashSet不能存相同的值的特性 遍历一次链表 存入hashSet中如果hashSet中不存在添加进去如果存在相同的引用直接返回这种方法实现简单显然不是美面试官所期望的时间复杂度为遍历链表O(N)空间复杂度为O(N).
下面就看代码实现:
public static LNode isLoopLink(LNode head){
if(head==null || head.next==null) return null;
HashSet<LNode> set=new HashSet<>();
LNode res=null;
for (LNode cur = head.next; cur!=null ; cur=cur.next) {
if (!set.contains(cur)){
set.add(cur);
}else {
res=cur;
break;
}
}
return res;
}
結果:
链表 :链表有环
环的节点3
方法2:快慢指针法
快慢指针解决法如过一个链表存在环 快慢指针一定会相遇 当fast指针到达链表时 向后运动一定会在环里循环 慢指针一定会相遇
下面就看代码实现:
//节点引用类
public class LNode {
int data;
LNode next;
}
我们可以先初始化一个链表
//构造链表
public static LNode constructList(){
int i=1;
LNode head=new LNode();
head.next=null;
LNode temp=null;
LNode cur=head;
for (; i <8 ; i++) {
temp=new LNode();
temp.data=i;
temp.next=null;
cur.next=temp;
cur=temp;
}
cur.next=head.next.next.next;
return head;
}
public static LNode isLoopLink(LNode head){
if(head==null || head.next==null) return null;
LNode slow,fast;
slow=head.next;
fast=head.next;
while(fast!=null && fast.next!=null){
slow=slow.next;
//比慢指针快一步
fast=fast.next.next;
if(slow==fast){
return slow;
}
}
return null;
}
需要找出环的位置具体代码:
/**
* 找出环节点
* @param head
* @param meetNode
* @return
*/
public static LNode findLoopNode(LNode head,LNode meetNode){
LNode first=head.next;
LNode second=meetNode;
while (first!=second){
first=first.next;
second=second.next;
}
return first;
}
初始化鏈表的時候因爲存在環打印會出現死循環
4567345673456734567345673456734567
結果
Files\Java\jdk1.8.0_74\jre\lib\rt.jar;E:\workspace\JavaAlgorithmInterview\out\production\JavaAlgorithmInterview" Link.isLoop
链表 :链表有环
6
3