LeetCode刷题之no.141

关键知识

链表的处理

解题思路

一种简单的做法就是顺序遍历每个结点,然后每次都判断该点是否在前面遍历过的结点中,可以采用两层遍历的做法或者是采用set来存储前面的结点,然后每次在set中find这个结点。但是set会将空间复杂度大大增加。
另一种做法就是采用快慢两个指针在链表中遍历,如果快慢指针会相遇,则说明链表中存在环,否则不存在。该做法的时间复杂度为O(n),空间复杂度为O(1),为最佳做法。

简单做法

首先初始化一个set,然后遍历链表,不断地比较该节点是否出现过,出现过则说明存在环,没出现过就将此节点加进set,直到遍历完整个链表。
时间复杂度: 平均为O(n),最差为O(n^2)
空间复杂度: O(n)

最佳解法

采用两个指针分别为fast和slow,fast指针遍历的速度为slow的两倍,如果在fast到达链表结尾时两个指针不相遇,则说明链表不存在环,如果存在环,由于两者速度不一样,必定相遇,且相遇也说明了链表存在环。
时间复杂度: O(n)
空间复杂度: O(1)

题目

Linked List Cycle

简答做法

class Solution {
public:
    bool hasCycle(ListNode *head) {
        set<ListNode*> sl;
        ListNode* p = head;
        while (p) {
        	if (sl.find(p) != sl.end()) return true;
        	else sl.insert(p);
        	p = p->next;
        }
        return false;
    }
};

最优解法

class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode *fast = head, *slow = head;
        if (!head) return false;
        if (head->next == nullptr) return false;
        if (head->next == head) return true;
        fast = head->next ? head->next->next : head->next;
        slow = head->next;
        while (fast) {
        	if (fast == slow) return true;
        	fast = fast->next ? fast->next->next : fast->next;
        	slow = slow ? slow->next : slow;
        }
        return false;
    }
};

题目地址

Linked List Cycle

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值