zoukankan      html  css  js  c++  java
  • ★ Linked List Cycle II -- LeetCode

    证明单链表有环路:

    本文所用的算法 能够 形象的比喻就是在操场其中跑步。速度快的会把速度慢的扣圈 

    能够证明,p2追赶上p1的时候。p1一定还没有走完一遍环路,p2也不会跨越p1多圈才追上 

    我们能够从p2和p1的位置差距来证明。p2一定会赶上p1可是不会跳过p1的 

    由于p2每次走2步。而p1走一步。所以他们之间的差距是一步一步的缩小,4,3,2,1,0 
    到0的时候就重合了。

    找到环路的起点:

    既然可以推断出是否是有环路,那改怎样找到这个环路的入口呢? 

    解法例如以下: 当p2依照每次2步,p1每次一步的方式走,发现p2和p1重合,确定了单向链表有                                        
    环路了。



    接下来。让p2回到链表的头部。又一次走,每次步长不是走2了,而是走1。那么当p1和p2再次 
    相遇的时候。就是环路的入口了。 

    这点能够证明的: 

    在p2和p1第一次相遇的时候,假定p1走了n步骤,环路的入口是在p步的时候经过的,那么有 

    1、p1走的路径: p+c = n;        c为p1和p2相交点,距离环路入口的距离。

    2、p2走的路径: p+c+k*L = 2*n。  L为环路的周长,k是整数; 

    将1式中的p+c=n代入到2式,整理得:n=k*L;


    所以,假设从p+c点開始,p1再走n步骤的话,还能够回到p+c这个点 

    同一时候p2从头開始走的话。经过n不,也会达到p+c这点 

    显然在这个步骤其中p1和p2仅仅有前p步骤走的路径不同,所以当p1和p2再次重合的时候。必 
    然是在链表的环路入口点上。 


    code

    //Given a linked list, return the node where the cycle begins. If there is no cycle, return null. 
    #include<iostream>
    #include<fstream>
    using namespace std;
    
    struct ListNode {
    	int val;
    	ListNode *next;
    	ListNode(int x) : val(x), next(NULL) {}
    };
    
    class Solution {
    public:
    	ListNode *detectCycle(ListNode *head) {
    		ListNode* fast_walker = head;
    		if (has_cycle(head, fast_walker)){
    			ListNode* cur = head;
    			while (fast_walker != cur){
    				fast_walker = fast_walker->next;
    				cur = cur->next;
    			}
    			return cur;
    		}
    		else return NULL;
    	}
    private:
    	bool has_cycle(ListNode* head , ListNode* fast_walker){
    		ListNode* slow_walker = head;
    		while (slow_walker && fast_walker){
    			fast_walker = fast_walker->next;
    			if (fast_walker) fast_walker = fast_walker->next;
    			else break;
    			slow_walker = slow_walker->next;
    			if (fast_walker == slow_walker) return true;
    		}
    		return false;
    	}
    };
    
    int main(){
    	fstream fin("test.txt");
    	ListNode* head(0);//此时并没有分配存储地址
    	ListNode* tmp = head;//此时相当于 tmp = NULL
    	int in = 0;
    	while (fin >> in){
    		if (!head) {
    			head = new ListNode(in);
    			tmp = head;
    		}
    		else{
    			while (tmp->next != NULL) tmp = tmp->next;
    			tmp->next = new ListNode(in);
    			tmp = tmp->next;
    			tmp->next = NULL;
    		}
    	}
    	//制造一个环
    	tmp->next = head->next;
    	Solution ss;
    	ListNode* retult = ss.detectCycle(head);
    	system("pause");
    	return 0;
    }


  • 相关阅读:
    PHP Context学习系列《十》
    学习php记录《九》
    学习php记录《八》
    php学习记录《七》
    换到新工作后
    学习php记录《六》
    学习php记录《五》
    学习php记录《四》
    学习php记录《三》
    html基础
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5316440.html
Copyright © 2011-2022 走看看