Linked List Cycle II

来源:互联网 发布:淘宝新手发布宝贝 编辑:程序博客网 时间:2024/06/10 04:08

题目名称
Linked List Cycle II—LeetCode链接

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

分析
  判断一个单链表是否有环,如果有,返回环的起始节点。我的做法是用一个set来存储遍历的节点,每遍历一个节点,便将该节点插入set中,当插入重复的元素时,说明有环,并且该重复元素就是环的起始节点。

C++代码

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode *detectCycle(ListNode *head) {        if(!head)            return NULL;        set<ListNode*> node;        ListNode* cur = head;        pair<set<ListNode*>::iterator,bool> p;        while(cur){            p=node.insert(cur);            if(!p.second)                return cur;            else                cur=cur->next;        }        return NULL;    }};

总结
  算法的时间复杂度非常高,因为每次插入节点都要判断插入的元素是否已经存在。还有一种很简单的方法,就是用两个指针,一个快指针,一个慢指针,开始时都指向头结点,快指针每次移动两个节点,慢指针每次移动一个节点,移动过程中如果两个指针相了,则证明单链表有环,然后让慢指针从头结点开始与快指针同时每次向后移动一个节点,当他们再次相遇时,相遇的节点就是环的起始位置。

ListNode *detectCycle(ListNode *head) {    if (head == NULL || head->next == NULL)         return NULL;    ListNode* firstp = head;    ListNode* secondp = head;    //isCycle为true则表明单链表有环    bool isCycle = false;    while(firstp != NULL && secondp != NULL) {        firstp = firstp->next;        if (secondp->next == NULL) return NULL;        secondp = secondp->next->next;        if (firstp == secondp) {             isCycle = true; break;         }    }    if(!isCycle)         return NULL;    firstp = head;    while( firstp != secondp) {        firstp = firstp->next;        secondp = secondp->next;    }    return firstp;}
0 0
原创粉丝点击