Leetcode 141 Linked List Cycle

Leetcode 141 Linked List Cycle

题目描述

Given a linked list, determine if it has a cycle in it.

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Example 1:

Input: head = [3,2,0,-4], pos = 1
Output: true
Explanation: There is a cycle in the linked list, where tail connects to the second node.

img

Example 2:

Input: head = [1,2], pos = 0
Output: true
Explanation: There is a cycle in the linked list, where tail connects to the first node.

img

Example 3:

Input: head = [1], pos = -1
Output: false
Explanation: There is no cycle in the linked list.

img

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-cycle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路解析
  • 方案一:

利用列表,遍历整个链表,如果列表中不含有当前结点,则将当前结点添加到列表中,如果遍历过程中发现列表中已经含有当前结点,则可以判断该链表是含有环路的

class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if not head or head.next is None:
            return False
        temp = []
        while head:
            if head in temp:
                return True           
            temp.append(head)
            head = head.next
        return False

(注意:不要用结点的值来判断是否遍历到同一个结点,这样会导致无法处理含有值相同的多个结点的链表)

但是上述的算法存在一个问题,外层的while循环时间复杂度为 O ( N ) , N 为 链 表 长 度 O(N),N为链表长度 O(N),N,在内层的if语句判断temp是否含有某结点时,其时间复杂度为 O ( M ) , M 为 t e m p 的 当 前 长 度 O(M),M为temp的当前长度 O(M)Mtemp,整个算法的时间复杂度为 O ( M ∗ N ) O(M*N) O(MN),空间复杂度为 O ( N ) O(N) O(N)。显然是一个低效的算法.

我们可以对内层if语句进行改进,将列表改为hash表,哈希表判断是否含有某元素的时间复杂度 O ( 1 ) O(1) O(1)

  • 方案一的改进:

将列表换为哈希表,可以直接使用python中的字典,提高查找效率。代码如下:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if not head or head.next is None:
            return False
        temp = {}
        while head:
            if temp.get(head):
                return True           
            temp[head] = 1
            head = head.next
        return False      

速度噌的一下就上去了。时间复杂度为 O ( N ) O(N) O(N),空间复杂度为 O ( N ) O(N) O(N)

  • 快慢指针法

慢指针每次走一步,快指针每次走两步,如果链表中存在环,快慢指针一定会相遇

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if not head or head.next is None:
            return False    
        slow = head
        fast = head.next
        while slow != fast:
            if fast and fast.next:
                slow = slow.next
                fast = fast.next.next
            else:
                return False
        return True

时间复杂度为 O ( N + K ) , N 为 链 表 长 度 , K 为 环 路 部 分 长 度 O(N+K),N为链表长度,K为环路部分长度 O(N+K),NK,空间复杂度为 O ( 1 ) O(1) O(1)

需要证明快慢指针一定会相遇。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值