LeetCode-142. Linked List Cycle II-using C/C++判断立案表内是否有环,有的话找到环的起始结点

【题目描述】                                tag:Linked List                   difficulty:Medium

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Note: Do not modify the linked list.

Follow up:
Can you solve it without using extra space?

即:尽量在不用额外空间的情况下,先判断这个链表是否有环,如果没有那么返回NULL,如果有那么返回指向开始成环的那个节点。

【函数形式】

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) 
{
}

【解题思路】

判断链表是否有环的方法在141里面已经提到,不再赘述。在这基础上我们发现,如果从成环的那个节点开始用两个指针遍历链表(一个逐个遍历,另一个隔一个一遍历),那么这两个指针也将会在这个开始成环的节点相遇,基于这个发现,便有了以下这个可行方案。

【代码如下】

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* p = head;
    struct ListNode* q = head;
    struct ListNode* t = head;
    int flag = 0;        //如果这个链表有环那么flag为1,便于继续下一步寻找环的起始结点
    if(head == NULL)
        return NULL;
    if(head->next == head)
        return head;
    while(p->next != NULL && q->next != NULL)
    {
        p = p->next->next;
        q = q->next;
        if(p == NULL)
            return NULL;
        if(p == q)
        {
            flag = 1;
            break;
        }  
    }
    if(flag == 1)
    {
        if(t == p)
            return head;
        else
        {
            p = head->next;
            q = head->next;
            while(t != NULL)
            {
                t = t->next;
                p = p->next->next;
                q = q->next;
                while(p != q)
                {
                    p = p->next->next;
                    q = q->next;
                }
                if(t == p)
                    return t;
                else
                {
                    p = t->next;
                    q = t->next;
                }
            }
            
        }
    }
    return NULL;
}

猜你喜欢

转载自blog.csdn.net/weixin_32549789/article/details/79580853