一、 LeetCode 142
1.1 哈希解法
-
思路1:
用hash表存储,如果遇到重复的节点,则为环的入口。 -
代码如下:
class Solution(object):
def detectCycle(self, head):
if not head:
return None
hash = {head}
while head.next != None:
head = head.next
if head in hash:
return head
else:
hash.add(head)
return None
1.2 快慢指针解法
- 思路2:
用快慢指针,快指针每次走两步,慢指针每次走一步。相遇后,慢指针回到起点,快指针走一步,则在环入口相遇。证明如下。
假设快慢指针在环中相遇如下:
- 假设起点到环入口距离为m
- 环的长度为n
- 两指针交点离环入口距离为x
则慢指针总共走了m+x步。
快指针总共走了2m+2x步,减去起点到交点的距离,则快指针在环内共走了m+x步,假设正好走了z圈。即有等式(m+x)/n=z。相遇后将慢指针移到起点,现在快指针在环内走n-x步,慢指针走m步。则满足关系m = (n-x) + (z-1)*n,即慢指针在环内绕z-1圈后与慢指针在环入口相遇。
- 代码如下:
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head:
return None
p1 = p2 = head
while True:
if p2.next is None or p2.next.next is None:
return None
p1 = p1.next
p2 = p2.next.next
if p1 == p2:
break
p1 = head
while p1 != p2:
p1 = p1.next
p2 = p2.next
return p1
二、 LeetCode 206 反转链表
Reverse a singly linked list.
Example:
Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL
-
思路:
用head遍历,一个指针p指向head前一个结点,一个指针n指向head后一个结点,当head为空时,返回p结点即可。 -
代码如下:
class Solution:
def reverseList(self, head):
p = None
n = head
while head is not None:
n = n.next
head.next = p
p = head
head = n
return p