一、环形链表
1、问题描述
给定一个链表,判断链表中是否有环。
2、问题分析
定义两个指针,从头节点开始,两个指针都向右移动,但是设置他们的移动速度不一样,如果为环形链表,则指针肯定会相遇。若为直链表,两个指针至少有一个为空。
3、代码
/**
* 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 p1 = head;
ListNode p2 = head;
boolean flag = false;
while(p1!=null&&p2!=null&&p2.next!=null){
p1 = p1.next;
p2 = p2.next.next;
if(p1==p2){
flag = true;
break;
}else if(p1==null || p2==null ){
flag = false;
}
}
return flag;
}
}
二、环形链表2
1、问题描述
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
2、问题分析
定义两个指针,从头节点开始,两个指针都向右移动,但是设置他们的移动速度不一样,如果为环形链表,则指针肯定会相遇。若为直链表,两个指针至少有一个为空。可以通过找到入口节点的规律来实现,比较麻烦。
换另外一种方法,通过哈希表来存储每次遍历的节点,如果某个节点刚好在哈希表中已经出现了,则这个节点就是所要找的环形节点的入口,返回这个节点,否则返回null。
3、代码
/**
* 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) {
Set<ListNode> hmap = new HashSet<ListNode>();
ListNode temp = head;
while(temp!=null){
if(hmap.contains(temp)){
return temp;
}
hmap.add(temp);
temp = temp.next;
}
return null;
}
}