返回
从基础到实践:掌握K个一组翻转链表算法(LeetCode第25题)
前端
2023-09-27 03:02:54
算法(leetode,附思维导图 + 全部解法)300题之(25)K 个一组翻转链表
一、题目
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
二、解法总览(思维导图)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bS2GDg0P-1664783216938)(思维导图.png)]
三、全部解法
1. 方案1
1)代码:
def reverseKGroup(head, k):
if not head or k == 1:
return head
# 找到要翻转的子链表的尾节点
tail = head
for i in range(1, k):
tail = tail.next
if not tail:
return head
# 翻转子链表
newHead = reverseList(head, tail)
# 将子链表的下一个节点作为新的头节点
head.next = reverseKGroup(tail.next, k)
# 返回翻转后的子链表
return newHead
def reverseList(head, tail):
prev = None
curr = head
while curr != tail:
next = curr.next
curr.next = prev
prev = curr
curr = next
# 将尾节点的下一个节点指向原来的头节点
tail.next = prev
# 返回翻转后的链表的头节点
return tail
2. 方案2
1)代码:
def reverseKGroup(head, k):
if not head or k == 1:
return head
# 创建一个哑节点作为新的头节点
dummy = ListNode(0)
dummy.next = head
# 指针指向哑节点
prev = dummy
while True:
# 找到要翻转的子链表的尾节点
tail = prev
for i in range(k):
tail = tail.next
if not tail:
return dummy.next
# 翻转子链表
newHead = reverseList(prev.next, tail)
# 将子链表的下一个节点作为新的头节点
prev.next = newHead
# 将子链表的尾节点的下一个节点指向原来的头节点
tail.next = prev.next
# 将prev指针指向翻转后的子链表的尾节点
prev = tail
# 返回翻转后的链表的头节点
return dummy.next
def reverseList(head, tail):
prev = None
curr = head
while curr != tail:
next = curr.next
curr.next = prev
prev = curr
curr = next
# 将尾节点的下一个节点指向原来的头节点
tail.next = prev
# 返回翻转后的链表的头节点
return tail
总结
这道题考察了链表的翻转以及递归和迭代的应用。
递归的解法比较简单,但是空间复杂度较高,因为需要不断创建新的栈帧。
迭代的解法相对复杂一些,但是空间复杂度较低,只需要一个指针指向翻转后的子链表的尾节点。
希望这篇文章能对大家有所帮助。