如何判斷一個單鏈表是否有環?
static class LinkedNode<T>{
private T t ;
private LinkedNode<T> next = null;
public LinkedNode(T t) {
this.t=t;
}
public LinkedNode<T> getNext() {
return next;
}
public void setNext(LinkedNode<T> next) {
this.next = next;
}
public String toString(){
return String.valueOf(t) ;
}
}
public static void main(String[] args) {
/**
* 造一個有環鏈表
*/
LinkedNode<String> l = new LinkedNode<String>("!");
LinkedNode<String> node = null;
LinkedNode<String> last = l;
for(int i=0;i<5;i++){
LinkedNode<String> temp = new LinkedNode<String>(i+"");
last.setNext(temp);
last = temp;
if(i==2){
node = temp;
}
if(i==4){
temp.setNext(node);
}
}
/**
* 尋找環入口
*/
System.out.println(findSingleLinkedRing(l));
}
/**
如何判斷一個單鏈表是否有環?
有環返回進入環的第一個節點,無環返回空
時間復雜度O(N),額外空間復雜度O(1)
*
*
*/
public static LinkedNode<String> findSingleLinkedRing(LinkedNode<String> l){
LinkedNode<String> index1 = l;
LinkedNode<String> index2 = l;
try{
while(true){
/**
* 慢指針
*/
index1 = index1.getNext();
/**
* 快指針
* 無環會出java.lang.NullPointerException
*/
index2 = index2.getNext().getNext();
/**
* 無重復則不存在環點
*/
if(index1==null || index2 == null){
return null;
}
/**
* 有重復則將快指針從頭單位步長執行,慢指針從之前重復位置執行
*
*/
if(index1 == index2){
index2 = l;
while(true){
index1 = index1.getNext();
index2 = index2.getNext();
/**
* 再次重合位置為入環位置
*/
if(index1 == index2){
return index1;
}
}
}
}
}catch(NullPointerException e){
return null;
}
}
}
如何判斷一個單鏈表是否有環?