141. Linked List Cycle
https://leetcode.com/problems/linked-list-cycle/
题目描述
Given a linked list, determine if it has a cycle in it.
Return True or False
思路1
最常规的思路,直接开辟一个list存放所有节点,每次都判断当前节点的子节点是否在list中,如果在的话说明存在loop,但是时空复杂度都为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
"""
nodeList = []
while head:
if head in nodeList:
return True
else:
nodeList.append(head)
head = head.next
return False
思路2
因为涉及到loop, 可以将问题考虑成一个追及问题, 用Walker和runner表示不同前进速度的指针, 如果list有loop那么他们必然在某一点相遇.
证明过程如下:
if there are loops:
2 * time - looplength * cycles = 1 * time;
then we get 1 * time = looplength * cycles;
because time can be any number, so there must be a number equals to the value of looplength times cycles
代码
# 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):
def hasCycle(self, head):
if head == None : return False
walker = head
runner = head
while runner.next!=None and runner.next.next!=None:
walker = walker.next
runner = runner.next.next
if walker == runner: return True
return False
142. Linked List Cycle II
https://leetcode.com/problems/linked-list-cycle-ii/
题目描述
Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
和第一题不同的是要返回cycle的起点
思路
同样用两个快慢指针相遇来判断是否循环, 但是在两点相遇时, 此时需要加入一个新的指针, 从起点出发, 新指针和满指针同时以相同速度前进, 必然会在循环起点相遇, 数学证明如下:
When fast and slow meet at point p, the length they have run are ‘a+2b+c’ and ‘a+b’.
Since the fast is 2 times faster than the slow. So a+2b+c == 2(a+b), then we get ‘a==c’.
So when another slow2 pointer run from head to ‘q’, at the same time, previous slow pointer will run from ‘p’ to ‘q’, so they meet at the pointer ‘q’ together.
代码
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if head == None: return None
walker = head
runner = head
while walker.next != None and runner.next != None and runner.next.next != None:
walker = walker.next
runner = runner.next.next
if walker == runner:
walker2 = head
while walker!= walker2:
walker = walker.next
walker2 = walker2.next
return walker
return None