劍指offer23——鏈表中環的入口節點

判斷單鏈表中有沒有環,如果有找到環的入口節點。

 

三個問題:

1、如何確定鏈表中包含環:兩個指針,一個指針一次走一步,一個指針一次走兩步。如果走得快的指針追上了走得慢的指針,則說明鏈表包含環; 如果走得快的指針走到了鏈表末尾(p->next == NULL)都沒有追上第一個指針,則無環。

2、如何找到環的入口:定義兩個指針p1,p2指向頭結點,如果環有n個結點, 則p1先移動n步,然後兩個指針以相同的速度向前移動。當p2指向環的入口節點時,p1已經圍繞着環走了一圈又回到了入口節點。

3、如何得到環中節點數目:1中相遇的兩個指針指向的結點一定在環中,可以從這個節點出發,一邊繼續移動一邊計數,當再次回到這個節點時,就可以得到環中節點數了。

//判斷鏈表內是否包含環
//找到快慢指針相遇的節點,此節點必定在環內
ListNode* meetingNode(ListNode* head){
	if(head == NULL)
		return NULL;
	ListNode* slow = head->next;
	if(slow == NULL)
		return NULL;
	ListNode* fast == slow->next;
	while(fast != NULL && slow != NULL){
		if(fast == slow)
			return fast;
		slow = slow->next;
		fast = fast->next;
		if(fast != NULL)
			fast = fast->next;
	}
	return NULL:
}

//得出環中節點數目,並找到環的入口節點
ListNode* EntryNodeOfLoop(ListNode* head){
	ListNode* meetingNode = meetingNode(head);
	if(meetingNode == NULL)
		return NULL;
	
	//找到環中節點數目
	int nodesInLoop = 1;
	ListNode* m = meetingNode;
	while(m->next != meetingNode){
		m = m->next;
		nodesInLoop++;
	}
	
	m = head;
	for(int i=0; i<nodesInLoop; ++i){
		m = m->next;
	}
	ListNode* n = head;
	while(m != n){
		m = m->next;
		n = n->next;
	}
	return m;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章