很好的问题!
现在我也明白这个问题了! (^_^)
这是链表中非常常见的问题,我们在遍历链表或执行任何其他操作时,应始终注意语句的更改顺序。
问题是,如果我们的语句中某些必需的顺序被遗漏(这里就是这种情况),最终会发生以下两种情况之一:
- 如果您愿意,任何一个节点都会错过到下一个节点的链接,并且该节点将变为无链接;
- 或者一个节点会链接回它自己(像一个圆圈)并且列表将变得过时;
您的代码具有正确的顺序可以在不超过时间限制的情况下正常工作(刚刚测试):
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def reverseKGroup(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
h = jump = ListNode(0)
h.next = left = right = head
while True:
i = 0
while i < k and right:
i += 1
right = right.next
if i == k:
prev = right
cur = left
for _ in range(k):
cur.next, cur, prev = prev, cur.next, cur
jump.next, jump, left = prev, left, right
else:
return h.next
我们也可以使用辅助函数。这将在没有超过时间限制 (TLE) 的情况下通过:
class Solution:
def reverseKGroup(self, head, k):
def rev(head, count):
prev, curr, next = None, head, head
while count > 0:
next = curr.next
curr.next = prev
prev, curr, count = curr, next, count - 1
return (curr, prev)
count, curr = 0, head
while curr and count < k:
curr, count = curr.next, count + 1
if count < k:
return head
new_head, prev = rev(head, count)
head.next = self.reverseKGroup(new_head, k)
return prev
这里是 LeetCode 的官方解决方案,带有解释性 cmets:
递归
class Solution:
def reverseLinkedList(self, head, k):
# Reverse k nodes of the given linked list.
# This function assumes that the list contains
# atleast k nodes.
new_head, ptr = None, head
while k:
# Keep track of the next node to process in the
# original list
next_node = ptr.next
# Insert the node pointed to by "ptr"
# at the beginning of the reversed list
ptr.next = new_head
new_head = ptr
# Move on to the next node
ptr = next_node
# Decrement the count of nodes to be reversed by 1
k -= 1
# Return the head of the reversed list
return new_head
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
count = 0
ptr = head
# First, see if there are atleast k nodes
# left in the linked list.
while count < k and ptr:
ptr = ptr.next
count += 1
# If we have k nodes, then we reverse them
if count == k:
# Reverse the first k nodes of the list and
# get the reversed list's head.
reversedHead = self.reverseLinkedList(head, k)
# Now recurse on the remaining linked list. Since
# our recursion returns the head of the overall processed
# list, we use that and the "original" head of the "k" nodes
# to re-wire the connections.
head.next = self.reverseKGroup(ptr, k)
return reversedHead
return head
迭代
class Solution:
def reverseLinkedList(self, head, k):
# Reverse k nodes of the given linked list.
# This function assumes that the list contains
# atleast k nodes.
new_head, ptr = None, head
while k:
# Keep track of the next node to process in the
# original list
next_node = ptr.next
# Insert the node pointed to by "ptr"
# at the beginning of the reversed list
ptr.next = new_head
new_head = ptr
# Move on to the next node
ptr = next_node
# Decrement the count of nodes to be reversed by 1
k -= 1
# Return the head of the reversed list
return new_head
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
ptr = head
ktail = None
# Head of the final, moified linked list
new_head = None
# Keep going until there are nodes in the list
while ptr:
count = 0
# Start counting nodes from the head
ptr = head
# Find the head of the next k nodes
while count < k and ptr:
ptr = ptr.next
count += 1
# If we counted k nodes, reverse them
if count == k:
# Reverse k nodes and get the new head
revHead = self.reverseLinkedList(head, k)
# new_head is the head of the final linked list
if not new_head:
new_head = revHead
# ktail is the tail of the previous block of
# reversed k nodes
if ktail:
ktail.next = revHead
ktail = head
head = ptr
# attach the final, possibly un-reversed portion
if ktail:
ktail.next = head
return new_head if new_head else head
参考文献