2021-06-24 k个一组反转链表

这篇博客介绍了如何解决LeetCode上的一个链表问题,即反转链表中每k个节点组成的一组。博主首先遇到了困难,但通过阅读题解并实践,最终理解了算法。文章提供了详细的解题代码,包括反转链表的辅助函数,以及处理k个一组反转的核心逻辑,特别注意了边界情况和链表连接的操作。
摘要由CSDN通过智能技术生成

leetcode每日一题指k个一组反转链表

题目链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group/submissions/

题目描述:

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

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

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

例子

输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]

题解

今天的这道题本以为反转链表会了一下就做出来了,结果写了好久发现还是不对,链表的题真是恶心到我了。

然后看了题解,才恍然大悟。

我是看题解看懂的,所以敲了两遍,但是不知道如何描述,全都在注释里面。代码如下:

代码如下:
    public ListNode reverseKGroup(ListNode head, int k) {
            //如果只有一个节点或者没有节点,直接返回
            if (head == null || head.next == null) {
                return head;
            }
            //定义一个假的节点。
            ListNode dummy = new ListNode(0);
            //假节点的next指向head。
            // dummy->1->2->3->4->5
            dummy.next = head;
            //初始化pre和end都指向dummy。pre指每次要翻转的链表的头结点的上一个节点。end指每次要翻转的链表的尾节点
            ListNode pre = dummy;
            ListNode end = dummy;
    
            //注意这里的条件是ens.next != null,也就是假如链表节点个数是k的整数倍的话,反转完后end指向最后一个节点,如果下一个没有了就结束循环,如果还有但是小于k个下面的循环和判断条件会控制
            while (end.next != null) {
                //循环k次,找到需要翻转的链表的结尾,这里每次循环要判断end是否等于空,因为如果为空,end.next会报空指针异常。
                //dummy->1->2->3->4->5 若k为2,循环2次,end指向2
                for (int i = 0; i < k && end != null; i++) {
                    end = end.next;
                }
                //如果end==null,即需要翻转的链表的节点数小于k,不执行翻转。
                if (end == null) {
                    break;
                }
                //先记录下end.next,方便后面链接链表
                ListNode next = end.next;
                //然后断开链表
                end.next = null;
                //记录下要翻转链表的头节点
                ListNode start = pre.next;
                //翻转链表,pre.next指向翻转后的链表。1->2 变成2->1。 dummy->2->1
                //这里的pre和dummy是一样的指向,因此pre.next相当于变成了dummy->2->1
                pre.next = reverse(start);
                //翻转后头节点变到最后。通过.next把断开的链表重新链接。
                start.next = next;
                //将pre换成下次要翻转的链表的头结点的上一个节点。即start
                pre = start;
                //翻转结束,将end置为下次要翻转的链表的头结点的上一个节点。即start
                end = start;
            }
            return dummy.next;
        }
        //链表翻转
        // 例子:   head: 1->2->3->4
        public ListNode reverse(ListNode head) {
            //单链表为空或只有一个节点,直接返回原单链表
            if (head == null || head.next == null) {
                return head;
            }
            //前一个节点指针
            ListNode preNode = null;
            //当前节点指针
            ListNode curNode = head;
            //下一个节点指针
            ListNode nextNode = null;
            while (curNode != null) {
                nextNode = curNode.next;//nextNode 指向下一个节点,保存当前节点后面的链表。
                curNode.next = preNode;//将当前节点next域指向前一个节点   null<-1<-2<-3<-4
                preNode = curNode;//preNode 指针向后移动。preNode指向当前节点。
                curNode = nextNode;//curNode指针向后移动。下一个节点变成当前节点
            }
            return preNode;
        }
        ```



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值