(python刷题)leetcode 第25题:K 个一组翻转链表

题目描述
在这里插入图片描述
解题思路

  1. 将整个链表分为已翻转区,待翻转区和未翻转区三个部分
  2. 初始化一个虚拟节点dummy,待翻转区的前驱节点pre和后继节点end初始化为pre=end=dummy
  3. 通过循环找到待翻转区的范围,每循环一次,end向前走一步,循环k次后end就位于待翻转区的末尾节点,初始化start=pre.next就得到了待翻转区的范围[start, end]
  4. 记录end的后一个节点next=end.next,以便翻转后将这三个部分进行连接,然后将end.next=null才能对其进行翻转操作
  5. 对待翻转区进行翻转,并使得pre指向翻转后的新节点,此时start为翻转后的尾节点,将start指向next,使得与下一个部分进行连接
  6. 更新pre和end,pre=end=start
  7. 重复1-6直到整个链表处理完成
  8. 另外,需要注意的是,如果待翻转区的长度小于k,那么则不翻转

为了更好的理解真个算法的过程,这里引用了 这篇博文的图
在这里插入图片描述
复杂度分析:
由于每次寻找待翻转区的范围需要循环k次,然后对待范围区翻转也需要遍历一次待翻转区,因此算法的时间复杂度为o(2n),即o(n)
由于即需要创建常数个变量,所以空间复杂度为o(1)

python代码

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def reverseKGroup(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        dummy = ListNode(0)
        dummy.next = head
        pre = end = dummy
        while end.next:
            for i in range(0, k):
                if end:
                    end = end.next
                else:
                    break
            if end:
                end_next = end.next
            else:
                break
            start = pre.next
            end.next = None
            pre.next = self.reverseList(start)
            start.next = end_next
            pre = end = start
        return dummy.next
    
    def reverseList(self, head):
        pre = None
        cur = head
        while cur:
            cur_next = cur.next 
            cur.next = pre
            pre = cur
            cur = cur_next
        return pre
                                
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章