Java 力扣25. K 个一组翻转链表

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

在这里插入图片描述
本题可以看作92. 反转链表 II的一个进阶题,反转多个给定长度的链表段。反转核心还是最基础的前后节点进行后移,如下:

while(cur != null){// 只要当前不为空 可以一致循环处理
            // 获取当前指针的下一节点
            ListNode next = cur.next;
            // 当前指针之前的下一个为 next ,现在反向指向前一个 pre
            cur.next = pre;
            // 向后移动继续下一个节点处理,例如开始是null,1 那么这是就变成 1,2开始反转指针
            pre = cur;
            cur = next;
        }

本题相对于92. 反转链表 II 多了反转多少个链表段,在解题时使用变量count为链表长度,然后每反转一个链表段count就减去K直到count小于K。每次反转一段时(K个节点)我们就使用前后节点指针反向,最终得到反转段右节点的下一节点(cur)和反转段的头节点(pre),然后将每个反转段进行关联。

代码如下:

	public ListNode reverseKGroup(ListNode head, int k) {
        int count = 0;
        ListNode countHead = head;
        while (countHead != null) {
            countHead = countHead.next;
            count++;
        }
        // 哨兵节点 及 每段前节点初始化
        ListNode dummy = new ListNode(0, head), segmentPre = dummy;
        //当前节点、 前一节点(此处为null,反转后的每段结果为pre) 初始化
        ListNode cur = head, pre = null;
        // ============= 只有当整除K时进行反转 start =============
        while (count >= k) {
            // ============= 每段进行指针反向操作 start =============
            int segmentK = k;
            while (segmentK > 0) {
                // 缓存下一节点便于后移
                ListNode next = cur.next;
                // 当前节点指针反向 指向前一节点
                cur.next = pre;
                // 前一节点后移
                pre = cur;
                // 当前节点后移
                cur = next;
                // 当前片段个数减一
                segmentK--;
            }
            // ============= 每段进行指针反向操作 end =============
            // ============= 每段进行指针反向操作 返回的结果为pre
            // ============= 每段进行首尾指向 start =============
            // 缓存下一节点便于后移 segmentPre.next = pre,segmentPre.next.next = cur
            // 相当于 segmentPre 只用了第二个节点(第一个为0即为哨兵节点),将上述反转段插入到第二个节点上(相对于某段而言,毕竟segmentPre会随之后移)
            ListNode next = segmentPre.next;
            // 设置每段下一次循环的当前节点 其实当前为 segmentPre.next
            segmentPre.next.next = cur;
            // 将上述反转的
            segmentPre.next = pre;
            // segmentPre后移
            segmentPre = next;
            // 数值一次减少K
            count -= k;
            // ============= 每段进行首尾指向 end =============
        }
        // ============= 只有当整除K时进行反转 end =============
        return dummy.next;
    }

运行结果如下:
(含有注释效果会低,去掉注释后内存由提升)
在这里插入图片描述

个人见解不喜勿喷!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值