LeetCode——环形链表

来源于http://blog.jobbole.com/106227/

给定一个链表,判断链表中是否有环。

进阶:
你能否不使用额外空间解决此题?

解法1:检查每个节点与前面所有节点中某个节点相等,若相等,则说明链表有环,否则比较下一个直至遍历完所有节点。

时间复杂度o(n^2),空间复杂度o(1)(没有用到额外空间)

解法2:创建一个以节点ID为键的Set集合,用来存储曾经遍历过的节点。然后同样是从头节点开始,依次遍历单链表的每一个节点。每遍历到一个新节点,就用新节点和Set集合当中存储的节点作比较,如果发现Set当中存在相同节点ID,则说明链表有环。

时间复杂度o(n),空间复杂度o(n)。

#include<cstdlib>
#include<set>
#include<iterator>
class Solution {
public:
    bool hasCycle(ListNode *head) {
        set<ListNode *> myset;
        set<ListNode *>::iterator pos;
        ListNode *node = head;
        while(node != NULL)
        {
            pos = myset.find(node);
            if(pos != myset.end())
            {
                return true;
            }
            else
            {
                myset.insert(node);
                node = node->next;
            }
        }
        
        return false;
        
    }
};

解法3:不使用额外空间,设置两个指针p1,p2,开始均指向头结点,然后每次p1向后移动一个节点,p2向后移动两个节点。然后比较两个指针指向的节点是否相同。如果相同,则判断出链表有环,如果不同,则继续下一次循环。有“环”自会“重逢”。

此方法也可以用一个更生动的例子来形容:在一个环形跑道上,两个运动员在同一地点起跑,一个运动员速度快,一个运动员速度慢。当两人跑了一段时间,速度快的运动员必然会从速度慢的运动员身后再次追上并超过,原因很简单,因为跑道是环形的。

#include<cstdlib>
#include<set>
#include<iterator>
class Solution {
public:
    bool hasCycle(ListNode *head) {
        if(head == NULL)
            return false;
        ListNode *p1,*p2;
        p1 = p2 = head;
        while(p2->next != NULL && p2->next->next != NULL)
        {
            p1 = p1->next;
            p2 = p2->next->next;
            if(p1 == p2)
            {
                return true;
                break;
            }                           
        }      
        return false;       
    }
};

运行出现下面的错误,代码复制到LeetCode官网上运行,报错:member.........   我就知道肯定又是关于NULL没弄对,第20行脑袋短路写成 || 了(上面代码已经更正了)。


AC,效率提高!。

猜你喜欢

转载自blog.csdn.net/eartha1995/article/details/80987563
今日推荐