leetcode(141). Linked List Cycle

来源:互联网 发布:网络棋盘游戏 编辑:程序博客网 时间:2024/06/15 18:59

problem

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

Follow up: Can you solve it without using extra space?

solution

第一种解法不考虑使用额外空间,使用hash set判断是否出现重复的节点,判断是否有环。

# Definition for singly-linked list.# class ListNode(object):#     def __init__(self, x):#         self.val = x#         self.next = Noneclass Solution(object):    def hasCycle(self, head):        """        :type head: ListNode        :rtype: bool        """        s = set()        while head:            if head in s:                return True            else:                s.add(head)                head = head.next        return False

下面这种解法是不使用额外空间的,它的想法是使用两个指针,step1每次走一步,step2每次走两步,如果这两个指针可以碰上那么一定有环,否则一定无环。

证明:
不妨设整个链表就是一个环,step2领先step1 k步,设环中一共有n个元素,n步后有(step2 - step1) % n == 0,所以不会出现有环却检测不到的情况,即循环中step1 is step2是有环的充要条件。
反例如果step1和step3的话,在n为奇数时永远不会有(step2 - step1) % n == 0,step1 is not step2 列表却有环,不是充要条件。

class Solution(object):    def hasCycle(self, head):        """        :type head: ListNode        :rtype: bool        """        step1 = head        step2 = head        while step1 and step2:            step1 = step1.next            tmp = step2.next            if tmp:                step2 = tmp.next            else:                return False            if step1 is step2:                return True        return False

is和==的区别
is是比较两个对象的是否是同一个对象(id是否相同),而==则是比较两个对象的值是否相等(应该就是调用__eq__方法),这是需要自己去实现的(运算符重载),也就是说在自定义对象中即使两个不同实例的所有值都相同,如果没有定义__eq__方法的话还是会返回False,因为默认的__eq__应该就是return两者是否是同一个元素。
所以==是通过运算符重载来比较两个对象是否相等(实际上可以自定义各种操作,见下面代码示例),而is就是用来比较是否是同一个对象,通常is的速度要快一点。
所以这里我们要使用is来判断是否是一个对象,而不是使用==值是否相等(虽然题目中node也没实现__eq__,但还是要理解语言的细节)。

class N:    def __init__(self, n):        self.n = n    def __eq__(self, N1):        #return self.n == N1.n        return Truen1 = N(1)n2 = N(2)#即使n1.n和n2.n不相等还是返回Trueprint(n1 == n2)
原创粉丝点击