leetcode之Linked List Cycle以及Linked List Cycle II

Given a linked list, determine if it has a cycle in it.

Follow up: Can you solve it without using extra space?

摘自剑指offer:当用一个指针遍历链表不能解决问题的时候,可以尝试用两个指针来遍历链表,可以让一个指针遍历的速度快一些,或者让他先在链表上走若干步。

相关的题目有:

求链表的中间节点,

判断一个单向链表是否形成了环形结构

判断有环链表的环的入口节点

一次遍历求链表的倒数第K个节点

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

判断是否有环代码如下:

public boolean hasCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        if(head==null||head.next==null){
        	return false;
        }
        while(slow.next!=null&&fast.next!=null&&fast.next.next!=null){
        	slow = slow.next;
        	fast = fast.next.next;
        	if(slow==fast){
        		return true;
        	}
        }
        return false;
    }

 判断环的入口点:

和剑指offer的第56题一样,也是用了两个指针,第一个指针从head向前走了环中节点个数步,第二个指针指向head,两个指针以同样的速度前进,知道两个指针相遇即为环入口点。

首先必须知道环中节点的个数,可以利用上题,找到两个指针相遇的地方即环中某个节点,然后开始计数。

代码如下:

public ListNode detectCycle(ListNode head) {
        ListNode meetNode = meet(head);
    	int nodeLoop = 1;
    	ListNode node1 = meetNode;
    	if(node1==null){
    	    return null;
    	}
    	while(node1.next!=meetNode){
    		node1 = node1.next;
    		nodeLoop = nodeLoop + 1;
    	}
    	ListNode node2 = head;
    	for(int i = 0;i<nodeLoop;i++){
    		node2 = node2.next;
    	}
    	ListNode node3 = head;
    	while(node2!=node3){
    		node2 = node2.next;
    		node3 = node3.next;
    	}
    	return node2;
    }
    public ListNode meet(ListNode head){
    	ListNode slow = head;
        ListNode fast = head;
        if(head==null||head.next==null){
        	return null;
        }
        while(slow.next!=null&&fast.next!=null&&fast.next.next!=null){
        	slow = slow.next;
        	fast = fast.next.next;
        	if(slow==fast){
        		return slow;
        	}
        }
        return null;
    }
原文地址:https://www.cnblogs.com/gracyandjohn/p/4433632.html