您的位置:首页 > 其它

leetcode(141). Linked List Cycle

2017-08-05 18:12 417 查看

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 = None

class 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 True

n1 = N(1)
n2 = N(2)
#即使n1.n和n2.n不相等还是返回True
print(n1 == n2)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode