咱们在上篇文章里面提到了链表的翻转,给定一个链表,对每两个相邻的节点做交换,并返回头节点,今天的这道题是它的升级版,以下:node
k个一组翻转链表python
给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。程序员
k 是一个正整数,它的值小于或等于链表的长度。若是节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。算法
示例 :微信
给定这个链表:1->2->3->4->5
函数
当 k = 2 时,应当返回: 2->1->4->3->5
指针
当 k = 3 时,应当返回: 3->2->1->4->5
code
说明 :blog
你的算法只能使用常数的额外空间。递归
你不能只是单纯的改变节点内部的值,而是须要实际的进行节点交换。
解题思路:
这道题让咱们以每K个为一组来翻转链表,其实是把原链表分红若干个小段,而后对没一个小段进行翻转。那么咱们就能想到他是须要两个函数的,一个是来作分段的,一个是在对每一段作翻转的。咱们就以题中给出的例子来看的话,1>2>3>4>5, k=3.通常在处理链表问题的时候,由于单向链表是不可逆的,只能从前日后遍历,因此咱们通常在开头添加一个头结点,记录当前最新的头结点,值通常给为-1,那么新的链表就变为了-1>1>2>3>4>5.k=3,那么咱们须要把1>2>3作翻转,作翻转的时候咱们须要两个指针,pre和next分别指向要被翻转的链表的先后的位置,在这里也就是pre=-1,next=4,那么翻转完1>2>3以后变为-1>3>2>1>4>5,这个时候的pre指针应该是1。以下:
-1->1->2->3->4->5 | |
pre next
-1->3->2->1->4->5 | | pre next
就这样循环,只要循环了k个节点,就能够调用翻转函数来进行局部的翻转,翻转函数返回翻转后的链表的新的pre节点,实现方法以下:
def reverseOneGroup(pre_node, next_node): last_node = pre_node.next cur_node = last_node.next while cur_node != next_node: last_node.next = cur_node.next cur_node.next = pre_node.next pre_node.next = cur_node cur_node = last_node.next return last_node
在翻转函数中,定义两个三个指针,一个是pre指针,一个是last指针,一个是cur指针,pre指针是链表的头指针,cur指针是目前循环到的节点指针,last指针是当前循环到指针cur的前置节点指针,每次翻转cur的时间,只须要把last的next指向cur的next,cur的next指向pre的next,pre的next指向cur就好,而后cur就迭代下一个node,为last的next指针。整体的实现代码以下:
# Definition for singly-linked list. class ListNode(object): def __init__(self, x): self.val = x self.next = None def reverseOneGroup(pre_node, next_node): last_node = pre_node.next cur_node = last_node.next while cur_node != next_node: last_node.next = cur_node.next cur_node.next = pre_node.next pre_node.next = cur_node cur_node = last_node.next return last_node class Solution(object): def reverseKGroup(self, head, k): """ :type head: ListNode :type k: int :rtype: ListNode """ if k == 1 or not head: return head dump = ListNode(-1) dump.next = head pre = dump cur = head i = 0 while cur: i += 1 if i % k == 0: pre = reverseOneGroup(pre, cur.next) cur = pre.next else: cur = cur.next return dump.next
个人这个实现方法应该是我能想到的最常规,最简单的算法,确定会有其余的算法实现,你们能够探讨一下,好比在一个函数里实现,好比像上一篇文章同样使用递归,你们能够一块儿交流,欢迎给我留言,交流。
coding交流群:226704167,,郑州程序员群:59236263愿和各位一块儿进步!
微信公众号: