# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
206 Reverse Linked List
class Solution:
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
cur, pre = head, None
while cur:
# 反转后, 更新pre指针
cur.next, pre, cur = pre, cur, cur.next
return pre
24 Swap Nodes in Pairs
class Solution:
def swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
pre, pre.next = self, head
while pre.next and pre.next.next:
a = pre.next
b = a.next
# 三个节点进行交换: pre->a->b->c, pre->b->a->c
pre.next, b.next, a.next = b, a, b.next
# 更新pre指针位置
pre = pre.next.next
return self.next
141 Linked List Cycle
- 法一:用集合记录每个节点的值,同时进行查重。O(n)的空间时间复杂度
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
# init
d = set()
p = head
while p and p.next:
if p not in d: # search
d.add(p) # insertion
p = p.next # move
else:
return True
return False
- 法二:双指针,两个指针移动速度一快一慢。O(1)的空间复杂度,O(N)的时间复杂度
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
slow = fast = head
while fast and fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
142 Linked List Cycle II
同上两种方法,其中双指针方法,多画画图就能发现个规律:迭代次数等于环节点数。因此这里可以知道头结点到环入口等于相遇点再次到达环入口,利用这个等式可以知道求解该题
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# set method
d = set()
p = head
while p:
if p not in d:
d.add(p)
p = p.next
else:
return p
return None
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# two pointer
slow = fast = head
while fast and fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
# 如果相遇,慢指针从头走,快指针以1为步长继续走,相遇时即为环入口
if slow == fast:
slow = head
while slow != fast:
slow = slow.next
fast = fast.next
return slow
return None
25 Reverse Nodes in k-Group
class Solution:
def reverseKGroup(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
pre, pre.next = self, head
while 1:
# 这里用一个常数k的额外空间来记录
temp = []
for i in range(k):
temp.append(pre.next)
if pre.next == None:
pre.next = temp[0]
return self.next
pre.next = pre.next.next
# pre.next = head
# exchange node
tempp = temp[-1].next # 临时记录下一个节点的地址
pre.next = temp[-1] # 把最后一个节点放在最开始
for i in range(k-1,0,-1): # 中间的节点依次换方向
temp[i].next = temp[i-1]
temp[0].next = tempp # 指向第20行记录的地址
# move pre
for i in range(k):
pre = pre.next
总结一下:链表的题,通常搞定一组操作后就是while到表尾。应该注意边界问题,有些问题有点绕,链来链去的,求解时可以把头几次的迭代画出来。