09 环形链表

16 阅读1分钟

题目

image.png

image.png

思路

环形链表思路

  • 建立好链表之后。先用快慢指针,判断是否有环:快指针走两步,慢指针走一步;若有环,最终它们会重合在一个结点上。

  • 确定有环之后,再定义两个指针存放相遇点和头结点,然后依次往后走,若两指针所指相等,该结点就是环入口,返回该结点。 (自己过一遍就明白了,但是思路比较难想)

#include<stdio.h>
#include<stdlib.h>
//定义链表结点
typedef struct ListNode{ 
	int val;
	struct ListNode *next;
}ListNode;
ListNode *detectCycle(ListNode *head);

int main(){
	ListNode *head=(ListNode*)malloc(sizeof(ListNode));
	head->val=3;
	ListNode *one=(ListNode*)malloc(sizeof(ListNode));
	one->val=2;
	ListNode *two=(ListNode*)malloc(sizeof(ListNode)); 
	two->val=0;
	ListNode *three=(ListNode*)malloc(sizeof(ListNode));
	three->val=-4;
	head->next=one;
	one->next=two;
	two->next=three;
	three->next=one;//形成环
	
	ListNode *posNode=detectCycle(head);
	printf("相交节点为:%d",posNode->val);
	return 0;
} 
ListNode *detectCycle(ListNode *head){
	ListNode *slow=head; 
	ListNode *fast=head;
	while(fast!=NULL && fast->next!=NULL){//是否有环 
		slow=slow->next;
		fast=fast->next->next;
		if(slow==fast){//快慢指针相遇 
			ListNode *index1=fast;//相遇点
			ListNode *index2=head;//头结点
			while(index1!=index2){
				index1=index1->next;
				index2=index2->next;
			} 
			return index2;
		} 
	}
	return NULL;
}