LeetCode hot 100 — 25. K 个一组翻转链表

题目信息

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

k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k的整数倍,那么请将最后剩余的节点保持原有顺序。

你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

示例 1:

复制代码
输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]

示例 2:

复制代码
输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]

示例三

**输入:**head = 1,2,k = 2

输出:2,1

思考过程和自写代码

差不多能够自己写出来了。

核心的逻辑也都放在注释里面了,将k个看成一个区间 / 一组,组内进行反转,然后连接组外(最开始只想到了尾部衔接,导致示例提交出了点问题,手写过程后排查出了问题,嘻嘻,好久没感受过这样的古法编程了....)

耗了一点功夫但是写出来了,唯一迭代的地方注释里面也有了,就是如何处理好示例三的边界(到底什么时候退出反转)

自写满分代码(带注释和思维过程)

python 复制代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
        '''
            跟上个题目差不多,从2扩充到了一个更大的群体k. 难点在于是否可以复用逻辑;如果可以复用的话,如何复用逻辑

            初步想法感觉还是需要把k个数据看作一个整体,而且必然不能和上次一样一个一个去修改
            在特定区间内如何反转一段链表,可以参考206反转链表
        '''
        res = ListNode(0, head)
        now_begin = head # 当前区间开始位置
        last_tail = res
        while now_begin: # k <= n,一定可以进行一次反转的
            next_begin = now_begin # next_begin表示下一个需要反转的区间的首个位置
            '''
            原本代码:
                for i in range(k): 
                    next_begin = next_begin.next if next_begin else None # 此时next_begin到达下一个区间需要反转的首个位置
                if next_begin is None: break # 当前区间也即不支持反转
            后因为示例三做出以下的调整,不能一概而论
            '''
            for i in range(k): 
                if not next_begin: return res.next # 先判断再跳转. 执行k次跳转,如果是可以反转的话k次必须都是可以执行的,也就是必须执行k次next_begin = next_begin.next,那么这k次中next_begin必定不是None. 如果next_begin提前进入了none,那就是有问题的(注意不能先跳转再判断,因为我允许next_begin是none,见示例三,此时刚好是k的倍数,允许反转)
                next_begin = next_begin.next
            
            pre = None
            curr = now_begin
            while curr != next_begin:
                next_node = curr.next
                curr.next = pre  # 
                pre = curr
                curr = next_node
            now_begin.next = next_begin # 区间尾部衔接,now_begin为当前区间的最后一个数字,指向下一个区间的起点
            last_tail.next = pre  # 区间首部衔接,上个区间的尾巴指向当前节点的首个数字(如果curr是下一个区间的起点,刚好pre就是原来排列位置当前区间的最后一个 / 现有排列位置的第一个)
            last_tail = now_begin # 当前区间的起点反转以后会变成最后一个
            now_begin = next_begin

        return res.next

代码纯享(复习用)

删去了大段的注释

python 复制代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:

        res = ListNode(0, head)
        now_begin = head # 当前区间开始位置
        last_tail = res
        while now_begin: # k <= n,一定可以进行一次反转
            next_begin = now_begin # next_begin表示下一个需要反转的区间的首个位置
        
            for i in range(k): 
                if not next_begin: return res.next
                next_begin = next_begin.next
            
            pre = None
            curr = now_begin
            while curr != next_begin:
                next_node = curr.next
                curr.next = pre  
                pre = curr
                curr = next_node

            now_begin.next = next_begin # 区间尾部衔接,now_begin为当前区间的最后一个数字,指向下一个区间的起点
            last_tail.next = pre  # 区间首部衔接,上个区间的尾巴指向当前节点的首个数字
            last_tail = now_begin # 当前区间的起点反转以后会变成最后一个
            now_begin = next_begin

        return res.next
相关推荐
爱读书的小胖42 分钟前
LeetCode 122:买卖股票的最佳时机 II(C)解题分析
算法
结局无敌43 分钟前
React Native for OpenHarmony 实战:三方库 react-native-modal-dialog 的鸿蒙化适配指南
深度学习·算法·react native·react.js·harmonyos
OPEN-F1 小时前
ROS2系列教程:上位机建图与导航(原理综合)
算法·机器人
weixin_307779131 小时前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
tomwang03222 小时前
路径优化建模、优化算法分类及工程化小结
算法·数学建模·分类
小羊没烦恼!2 小时前
Ajax与JSON的一些总结
android·java·前端·数据库·mysql·算法·okhttp
2501_926978332 小时前
人机通信协议--人和机器之间的交互想象
人工智能·经验分享·算法·ai写作
行者全栈架构师2 小时前
【鸿蒙心迹】互动卡片全链路——把核心功能放到桌面(FormKit 实战)(HarmonyOS 7.x)
前端·算法·架构
无定义_2 小时前
10.11日常训练
算法
Code_Solitude2 小时前
c语言:关于qsoet函数知识点
c语言·数据结构·算法