环形链表 II
方案一
还是要设快慢指针,不过这次要记录两个指针相遇的位置,当两个指针相遇了后,让其一指针从链表头开始,此时再相遇的位置就是链表中环的起始位置
因为快指针每次走2,慢指针每次走1,快指针走的距离是慢指针的两倍。而快指针又比慢指针多走了一圈。所以head到环的起点+环的起点到他们相遇的点的距离 与 环一圈的距离相等。现在重新开始,head运行到环起点 和 相遇点到环起点 的距离也是相等的,相当于他们同时减掉了 环的起点到他们相遇的点的距离
借助单链表实现
C-源代码
#include <stdlib.h>
#include "LinkList.h"
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode *fast = head;
struct ListNode *slow = head;
while (slow != NULL && fast != NULL && fast->next != NULL) {
fast = fast->next->next;
slow = slow->next;
if (slow == fast) {
fast = head;
while (fast != slow) {
fast = fast->next;
slow = slow->next;
}
return fast;
}
}
return NULL;
}
/**
创建环
@return 环
*/
struct ListNode *create_cycle_list1()
{
struct ListNode *node1 = (struct ListNode *)malloc(sizeof(struct ListNode));
node1->val = 1;
struct ListNode *node2 = (struct ListNode *)malloc(sizeof(struct ListNode));
node2->val = 2;
struct ListNode *node3 = (struct ListNode *)malloc(sizeof(struct ListNode));
node3->val = 3;
struct ListNode *node4 = (struct ListNode *)malloc(sizeof(struct ListNode));
node4->val = 4;
node1->next = node2;
node2->next = node3;
node3->next = node4;
node4->next = node2;
return node1;
}
void test_0142(void)
{
struct ListNode *l1 = create_cycle_list1();
struct ListNode *ret =detectCycle(l1);
printf("入环的第一个节点值:%d\n",ret->val);
}
网友评论