题目一:若有一个链表,如何判断链表是否存在环?
思路:如何判断有环,这里思考之后发现,判断是否有环可以参考两个人走路,一前一后,一快一慢。如果有环,两人必定相遇。因此这次也采用这种思路
首先写一个链表类
private class Node { private int data; private Node next; public Node(int data) { this.data = data; } }
然后写判断是否有环
这里首先声明两个同时指向头节点的节点,一个一次走两步,一个一次走一步,如果最终两个节点相遇,那么存在环,否则不存在。
private Node head; public LinkedList() { head = new Node(0); } public boolean isCircle(LinkedList linkedList) { //判断是否含有环 Node a = linkedList.head; //a指针走得快,每次2步 Node b = linkedList.head; //b指针走得慢,每次1步 if (head == null) { return false; } while(a.next != null && a.next.next!=null) { a = a.next.next; b = b.next; if (a==b) { return true; } } return false; }
题目二:如何计算该环的大小(长度)
思路:如果直接用a走的减去b走的,那么可能存在有时候a已经在环内转了好几圈然而b还没有到的情况。所以可以让ab从相遇的地方再走一圈。这一圈就是环的长度。
public int circleSize(LinkedList linkedList) { //判断环有多大 int size = 0; Node a = linkedList.head; Node b = linkedList.head; if (isCircle(linkedList)) { //如果存在环 while(a.next!=b.next.next) { //第一圈 a = a.next.next; b = b.next; if (a==b) { //第一次相遇 a = a.next.next; b = b.next; size++; while (a!=b) { //再走一圈 a = a.next.next; b = b.next; size++; } return size; } } } return 0; }