欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

leetcode(141):Linked List Cycle

程序员文章站 2024-03-17 10:09:46
...

题目:Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?

题目分析:判断一个链表中是否存在环,最主要的是判断是否重复遍历的问题。
第一个思路是利用额外的一个数组来进行判断,对于已访问的结点,将其放置在数组中,然后每次再利用数组来进行判断,是否已经访问过该结点。

# 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 head == None:
            return False
        node  = head.next
        cluster = [head]
        while node:
            if node not in cluster:
                cluster.append(node)
                node = node.next
            else:
                return True
        return False

虽然思路很顺畅,但是,很遗憾,算法不够巧妙,超时了,第14个测试用例,很长很长的,就挂在了这个地方。
leetcode(141):Linked List Cycle

此路不通,那我就换一个思路来走,哈哈,没有什么事是解决不了的。
第二种思路,来判断每个结点是否被访问过,还不占用额外的空间,那直接访问过的结点,赋一个取不到的值不就可以判断了,只要遍历到这个特殊的数值,不就代表已经访问过这个结点了嘛??

# 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 head == None:
            return False
        while head:
            if head.val != '1':
                head.val = '1'
                head = head.next
            else:
                return True
        return False

OK~~搞定,只是,现在这个链表完全被改的面目全非了,在日常生活中当然不能这样子处理,是达到目的了,但把之前的结点也改变了,所以,还是不好。
首先有一个概念在这个题中,需要弄明白,就是这个不需要额外的空间到底是个什么意思?不能赋新值?还是不能??应该是不能像第一种方式那样,需要一个列表或者集合来存放已访问过的结点吧;

大佬的程序:(这个是Tortoise and hare)

def hasCycle(self, head):
    try:
        slow = head
        fast = head.next
        while slow is not fast:
            slow = slow.next
            fast = fast.next.next
        return True
    except:
        return False

学习到了,简直了,大佬们的思想真的是清奇,脑回路清奇。在计算机科学中,周期检测或周期发现是算法中找到一个周期的问题序列的迭代函数值。大佬的算法中采用了龟兔赛跑算法(Tortoise and Hare Algorithm),又叫做Floyd判圈算法(Floyd Cycle Detection Algorithm)。可以用在有限状态机,迭代函数或者链表上判断是否存在环,以及求出该环的起点和长度的算法。
算法原理:如果存在环,则从同一个起点,以不同的速度前进的2个指针必定会相遇。
解释就是在操场上跑步,跑的快的人相当于2倍速,跑的满的人,是1倍速,则2倍速肯定会反超1倍速,此时超过的那个瞬间就是相等的瞬间。
证明方法: