关闭

【LeetCode】Linked List Cycle I&II

标签: algorithmleetcode
259人阅读 评论(0) 收藏 举报
分类:

Problem

这里写图片描述

Code

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) {
    if(head==NULL)
        return false;;
    struct ListNode *faster;
    struct ListNode *slower;
    faster = head->next;
    slower = head;
    while(true){
        if(faster==NULL)
            break;
        if(faster->next==NULL)
            break;
        if(faster==slower)
            return true;
        slower = slower->next;
        faster = faster->next->next;
    }
    return false;;
}
 /*似乎不能改变节点的结构,否则释放的时候会RTE
bool hasCycle(struct ListNode *head) {
    struct ListNode *tmp;
    while(head!=NULL){
        if(head==head->next)
            return false;
        tmp = head;
        head = head->next;
        tmp->next = tmp;
    }
    return true;
}
*/

Comment

This story tells me,the slower will always be overrun by the faster.


Problem

这里写图片描述

Code

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode *faster = head;
    struct ListNode *slower = head;
    struct ListNode *entry = head;
    while(faster!=NULL && faster->next!=NULL){
        faster = faster->next->next;
        slower = slower->next;
        if(slower==faster){
            while(slower!=entry){
                slower = slower->next;
                entry = entry->next;
            }
            return entry;
        }
    }
    return NULL;
}

 /*取巧的方法,如果测试集够大,那么这个方法还是错误的 : )
struct ListNode *detectCycle(struct ListNode *head) {
    while(head!=NULL){
        if(head->val == (int)head)
            return head;
        else
            head->val = (int)head;
        head = head->next;
    }
    return NULL;
}
*/

Alogrithm Description

Step 1: Determine whether there is a cycle

1.1) Using a slow pointer that move forward 1 step each time

1.2) Using a fast pointer that move forward 2 steps each time

1.3) If the slow pointer and fast pointer both point to the same location after several moving steps, there is a cycle;

1.4) Otherwise, if (fast->next == NULL || fast->next->next == NULL), there has no cycle.

Step 2: If there is a cycle, return the entry location of the cycle

2.1) L1 is defined as the distance between the head point and entry point

2.2) L2 is defined as the distance between the entry point and the meeting point

2.3) C is defined as the length of the cycle

2.4) n is defined as the travel times of the fast pointer around the cycle When the first encounter of the slow pointer and the fast pointer

According to the definition of L1, L2 and C, we can obtain:

the total distance of the slow pointer traveled when encounter is L1 + L2

the total distance of the fast pointer traveled when encounter is L1 + L2 + n * C

Because the total distance the fast pointer traveled is twice as the slow pointer, Thus:

2 * (L1+L2) = L1 + L2 + n * C => L1 + L2 = n * C => L1 = (n - 1)* C + (C - L2)

It can be concluded that the distance between the head location and entry location is equal to the distance between the meeting location and the entry location along the direction of forward movement.

So, when the slow pointer and the fast pointer encounter in the cycle, we can define a pointer “entry” that point to the head, this “entry” pointer moves one step each time so as the slow pointer. When this “entry” pointer and the slow pointer both point to the same location, this location is the node where the cycle begins.

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:43614次
    • 积分:1296
    • 等级:
    • 排名:千里之外
    • 原创:88篇
    • 转载:5篇
    • 译文:0篇
    • 评论:4条
    文章分类
    最新评论