25.K个一组翻转链表
题目
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例:
给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解思路
1>源代码
# Definition for singly-linked list.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def reverse(self, head, tail):
newtail = head
newhead = tail
cur = head.next
pre = head
rev_stop = tail.next
while(cur != rev_stop):
nex = cur.next
cur.next = pre
pre = cur
cur = nex
return newhead, newtail
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
if(k == 1):
return head
beforehead = ListNode()
beforehead.next = head
prev = beforehead
while head:
tail = prev
for i in range(k):
tail = tail.next
if not tail:
return beforehead.next
nex = tail.next
head, tail = self.reverse(head, tail)
prev.next = head
tail.next = nex
prev = tail
head = tail.next
return beforehead.next
2>算法介绍
这道题让我想到了之前做过的翻转链表的题目,不过本题和那题有些区别,但是毋庸置疑的是一定可以使用那题的思路。
既然是k个一组对链表进行操作,我们首先写一个函数reverse(),用来翻转链表。函数要求提供链表的head和tail指针,这个函数就是采用之前做过的翻转链表题目的思路,维护三个指针pre, cur, next,逐步对链表进行翻转。
reverse()返回的是翻转好的链表的新头和新尾指针。我们只需要在调用这个函数之前把这个子链表的头部的前一个节点、尾部的后一个节点保护好,在调用reverse()之后就只需要把链表接起来即可。
有了大体思路我们来思考一下细节,如何找到k个为一组的子链表呢?举例说明:
beforehead-> 1-> 2-> 3-> 4-> 5-> NULL
beforehead只是为了链表操作的便利添加的节点,现假设k=3,那么第一次传入的head就应该指向1,tail就应该指向3.我们可以用for循环来完成寻找tail的操作:
for i in range(k):
tail = tail.next
if not tail:
return beforehead.next
if语句的作用是,如果此时剩余节点数已经小于k,则可以弹出结果。
找到了head和tail,我们调用函数获得reverse过后的子链表的head和tail,并把链表连接起来。然后再更新prev和head指针,准备下一次调用reverse()函数。
这道题并没有什么很高深的算法,但是他对链表操作的熟练度要求很高,我也花了不少时间思考和模拟。继续加油!