环路检测

/*
给定一个有环链表,实现一个算法返回环路的开头节点。
有环链表的定义:在链表中某个节点的next元素指向在它前面出现过的节点,则表明该链表存在环路。


示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环。

进阶:
你是否可以不用额外空间解决此题?

来源:力扣(LeetCode)
*/
/*
说明:
1、快慢指针,快指针+2,慢指针+1,如果链表有环,一定会相遇;
2、第一次相遇后,慢指针再从head处+1,快指针从第一次相遇处+1,第二次相遇即为入口点;

|    x             |   y |  
--------------------------
      第二次相遇到 \     |
                    \    | 
				   w \	 | z
				  	  \	 |
				  	   \ | 
				  		\|-
						 第一次相遇
第一次相遇:
快:x+y+z+w+y+z
慢:x+y+z
==>	x+y+z+w+y+z = 2(x+y+z)				 
==> x + w = x + y
==> w = y
==> 第二次就在入口相遇						  
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct ListNode {
	int val;
	struct ListNode *next;
};

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode *quickNode = head, *slowNode = head;
	
	do {
		if (!quickNode || !slowNode || !quickNode->next || !quickNode->next->next) {
			return NULL;
		}
		quickNode = quickNode->next->next;
		slowNode = slowNode->next;
	} while(quickNode != slowNode);
	
	slowNode = head;
    while (slowNode != quickNode) {
		slowNode = slowNode->next;
		quickNode = quickNode->next;
	}

	return quickNode;
}

struct ListNode* createList(int* values, int len){
	int i = 0;
	struct ListNode *head = NULL, *tail = NULL, *node = NULL;
	
	if(!values || len==0) {
		return NULL;
	}
	
	for (i = 0; i < len; i++) {
		 node = (struct ListNode*)malloc(sizeof(struct ListNode));
		 if(!node) {
			exit(1);
		 }
		 node->val = values[i];
		 node->next = NULL;
		 if(!head){
			head = node;
			tail = head;
		 }else{
			tail->next = node;
			tail = node;
		 }
	}
	
	tail->next = head->next;

	return head;
}

void printList(struct ListNode* head,char* msg){
	struct ListNode* node = head;
	int i = 0;
	
	if (msg){
		printf("%s:",msg);
	} else {
		printf("list:");
	}
	
	while (node) {
		printf("%d  ",node->val);
		node = node->next;
	}
	printf("\r\n");
}

int main(){
	struct ListNode* head = NULL;
	int values[]={3,2,0,-4};

	head = createList(values,sizeof(values)/sizeof(values[0]));
	
	printf("val:%d\r\n",detectCycle(head)->val);
	
	//printList(head,"test list");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值