题目
原文:
Given a circular linked list, implement an algorithm which returns node at the beginning of the loop.
DEFINITION
Circular linked list: A (corrupt) linked list in which a node’s next pointer points to an earlier node, so as to make a loop in the linked list.
EXAMPLE
Input: A -> B -> C -> D -> E -> C [the same C as earlier]
Output: C
译文:
给一个循环链表,实现一个算法返回这个环的开始结点
定义
循环链表:链表中的一个结点指向先前已经出现过的结点,导致链表出现环
例如
输入:A->B->C->D->E->C [先前结点C已出现过]
输出:C
解答
一种简单直观的方法就是对于一个无环链表,它每个结点的地址都是不一样的, 而如果有环,指针沿着链表移动,那这个指针最终会指向一个已经出现过的地址,所以可以遍历链表的过程中,将一个个结点存进一个哈希表,并判断下一结点的对应值是否存在哈希表中,存在则返回该结点即可,如下
import java.util.*;
class Q2_5{
public static String loopStart(LinkList ll) {
HashSet<String> hs=new HashSet<String>();
Node<String> node=ll.head;
while(node!=null){
if(hs.contains(node.getData()))
return node.getData();
hs.add(node.getData());
node=node.getNext();
}
return "";
}
public static void main(String[] args){
String[] str={"A","B","C","D","E","C"};
LinkList<String> ll=new LinkList<String>();
for(int i=0;i<str.length;i++){
ll.add(str[i]);
}
System.out.println(loopStart(ll));
}
}
class Node<T>{
public T data;
public Node<T> next;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public Node<T> getNext() {
return next;
}
public void setNext(Node<T> next) {
this.next = next;
}
}
class LinkList<T>{
public Node<T> head;
public Node<T> tail;
private int size;
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public void add(T i){
//在链表结尾插入节点
Node<T> newnode = new Node<T>();
newnode.setData(i);
if(head == null){
head = newnode;
tail = newnode;
size ++ ;
}
else {
tail.setNext(newnode);
tail = newnode;
size ++ ;
}
}
public void print(){
if(head == null){
System.out.println("链表为空");
return;
}
Node<T> temp = head;
while(temp.getNext()!= null){
System.out.print(temp.getData().toString());
temp=temp.getNext();
}
System.out.println(temp.getData().toString());
}
}
另外还有一种比较巧妙的方法,利用floyd判圈算法(龟兔赛跑算法)的原理
未完待续。。。