算法题:25. K 个一组翻转链表 (困难)一次AC(题目+思路+代码+注释)

在这里插入图片描述

题目

  1. 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]

提示:
链表中的节点数目为 n
1 <= k <= n <= 5000
0 <= Node.val <= 1000

思路

其实你可以多次翻转看做是一次翻转,反复调用不就行了。
另外k个翻转其实就是选取这个子链然后全部翻转呗。
那么这个问题被拆解后就成了一个最简单的翻转链表题了。
由于是个单链表,翻转链表直接用个栈即可,一次AC ,so easy!

代码

public ListNode reverseKGroup(ListNode head, int k) {
        Stack<ListNode> stack = new Stack<>();
        ListNode ret = null;
        // p用来遍历链表  lastTail作为上一个链表的尾部节点
        ListNode p = head, lastTail = null;
        // 有节点则执行
        while (p != null) {
            // 截取一个长度为k的链表放入栈,准备倒转
            for (int i = 0; i < k && p != null; i++) {
                stack.add(p);
                p = p.next;
            }
            // 凑齐了k个就翻转
            if (stack.size() == k) {
                // 翻转后子链的头
                ListNode newHead = stack.pop();
                // 如果之前已经有链翻转过了,那就要把前面链的结尾链接到下一个链的头
                if (lastTail != null) {
                    lastTail.next = newHead;
                }
                // 子链的头
                head = newHead;
                // 第一次翻转的头要作为最终返回的头
                if (ret == null) {
                    ret = head;
                }
                // 开始翻转子链
                while (!stack.isEmpty()) {
                    ListNode pop = stack.pop();
                    newHead.next = pop;
                    newHead = pop;
                }
                // 存好这个子链的尾巴
                lastTail = newHead;
                // 把这个子链的尾巴链接上后面链的第一个节点
                newHead.next = p;
            }
        }

        return ret;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HumorChen99

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值