• 4-1


    25.k个一组翻转链表

    给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

    k 是一个正整数,它的值小于或等于链表的长度。

    如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

    示例 :

    给定这个链表:1->2->3->4->5

    当 k = 2 时,应当返回: 2->1->4->3->5

    当 k = 3 时,应当返回: 3->2->1->4->5

    说明 :

    你的算法只能使用常数的额外空间。
    你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

    Python most votes solution:

    # 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 = jump = ListNode(0)
            dummy.next = l = r = head
    
            while True:
                count = 0
                while r and count < k:   # use r to locate the range
                    r = r.next
                    count += 1
                if count == k:  # if size k satisfied, reverse the inner linked list
                    pre, cur = r, l
                    for _ in range(k):
                        cur.next, cur, pre = pre, cur.next, cur  # standard reversing
                    jump.next, jump, l = pre, l, r  # connect two k-groups
                else:
                    return dummy.next
    

    分析:

    • 在指针的移动过程中要注意三点:

      第1点:

      等号左边的next表示指向,右边的next表示位置。即:

      a)等号左边若有next,则表示等号左边的指针将指向等号右边的位置。如:

      first.next = second.next
      

      表示first将指向second的下一个位置,如图:

      b)等号左边若无next,则表示等号左边的指针将移动到等号右边的位置。如:

      first = second.next
      

      表示first将移动到second的下一个位置,如图:

      c)等号右边若有next,则表示等号右边指针的后面的位置。如b)中的例子所示。

      d)等号右边若无next,则表示等号右边指针的当前位置。如:

      first = second
      

      表示first将移动到second的位置处。如图:

      第2点:

      代码的写法不同,指针的移法也不同,可以分为“同步”移法和“异步”移法。

      (1)“异步”移法:代码中指针的移动是有先后顺序的。“异步”移动时,每一步的移动都是基于上一步的移动结果进行的,即在前一步的移动结果确定之后,才能进行当前步的移动。这种移法比较好理解,详见第0024题的分析。

      (2)“同步”移法:指针的移动是按“组”完成的,同组内的指针是同时移动的。“同步”移动时,同组内各指针的移动互不干扰,每个指针的移动都只基于这一组指针的初始状态,而与其他指针的状态无关。本例中的代码使用的就是这种移动方法,以下将具体分析本题中各指针的移动过程。

      假设k=3,则在第一个外层while循环的过程中,各指针的移动过程如下图所示(粉红色框表示第一个group,绿色框表示第二个group):

      第二个及以后的while循环中,指针的移动过程均和上面类似。

      算法处理最后几个不够k个一组的元素是通过条件if count == k来判断的。

    第3点:

    在指针移动的过程中,如果指向某节点的指针始终都没有移动(如指向节点a的指针head),则不管a节点本身如何移动,head指针都会始终指向a节点。在for循环的第三轮结束时,尽管节点a已经发生了很多变动,但jump.next始终都会指向该节点,直到jump指针本身发生变化。

  • 相关阅读:
    关于BufferefReader.readLine()方法的理解
    web.xml配置
    第一章 网络编程入门
    浅谈c++中map插入数据的用法
    c++中new的用法
    线程
    设计模式(九)Bridge模式
    设计模式(八)Abstract Factory模式
    牛逼的人,都不太要面子
    质量运营在美团点评智能支付业务测试中的初步实践
  • 原文地址:https://www.cnblogs.com/tbgatgb/p/11110764.html
Copyright © 2020-2023  润新知