赞
踩
本人一直在努力地积累Leetcode上用Python实现的题,并且会尽力讲清每道题的原理,绝不像其他某些博客简略地带过。
如果觉得讲的清楚,欢迎关注。
给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
思路:与两两交换节点其实挺类似,只不过现在变成K个一组一起交换。我定义了一个反转K个的函数reverse。这道题最难突破的在于如何K个一起翻转并且将第一次翻转和后面的翻转连续起来。K个一起翻转我利用了不断更新oldhead, newhead的方式,t 始终不动。如何把前后翻转连接?我reverse函数把最新的reverse区间的head return, 改变上一个reverse结尾的next,从而实现连接。
beat 91
- class Solution:
- def reverseKGroup(self, head, k):
- """
- :type head: ListNode
- :type k: int
- :rtype: ListNode
- """
- #保存头部节点
- t = head
- tot = 0
- p = t
- if k == 1:
- return head
- #用tot算出总节点数,知道什么时候该停止
- while p != None:
- p = p.next
- tot += 1
- #cnt表示目前为止一共reverse了几个节点
- cnt = 0
- #从头部开始遍历
- while t != None:
- #判断翻转K个是否越界
- if cnt + k <= tot:
- #分情况讨论,如果是第一次reverse
- if cnt == 0:
- head = self.reverse(t, k)
- cnt += k
- else:
- #如果不是第一次了
- #这里有个巧妙的地方,当我们进行完第一次后,t指向第一个reverse区间的最后一个节点
- i = t.next
-
- #通过函数传递一个newhead,用newhead才能改变t.next的值
- newhead = self.reverse(i, k)
- #翻转了K个,数量增加K个
- cnt += k
- #上个节点的尾部的下一个指向新头
- t.next = newhead
- #让t前进,i同样与一开始t一样指向reverse部分最后一个.
- t = i
- #越界就说明我们已经reverse了能reverse的部分,直接退出
- else:
- break
- return head
-
-
-
- def reverse(self, t, k):
- #记录目前reverse的数量
- count = 1
-
- oldhead = t
- while count < k:
- #每次循环都定义一个新头,这个newhead是t 的下一项。
- newhead = t.next
- #把新头从t的下一项删去
- t.next = newhead.next
- #让新头在t的前面
- newhead.next = oldhead
- #新头变成旧头
- oldhead = newhead
- count += 1
- #返回reverse完后最新的头
- return newhead
反思易错:翻转类题目第一次翻转与接下来的翻转要分开讨论。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。