K个节点的组内逆序调整

复制代码
package class04;

/***
 * K个节点的组内逆序调整
 *
 * 实现k个节点的小组内部逆序,如果最后一组不够k个就保持原顺序。
 * 例子:
 * 调整前:1->2->3->4->5->6->7->8,k = 3
 * 调整后:3->2->1->6->5->4->7->8
 */
// 测试链接:https://leetcode.com/problems/reverse-nodes-in-k-group/
public class Code04_ReverseNodesInKGroup {
    //LeeCode在线测试时,不要提交这个类
    public static class ListNode {
        public int value;
        public ListNode next;
    }

    public static ListNode reverseKGroup(ListNode head, int k) {
        ListNode start = head;
        ListNode end = getKGroupEnd(start, k);//end指向这一组的尾结点
        if (end == null) {//如果end == null,那么说明第一组都没有凑齐。直接返回原来的头节点head。
            return head;
        }
        //走到这一步,说明第一组凑齐了。
        head = end;//head抓住end,end即第一组的尾结点。
        //head打死也不撒手,就抓住end,不管你后边,别的节点怎么折腾,怎么翻转,最后就是要返回这个head。
        reverse(start, end);//翻转组内链表
        ListNode lastEnd = start;//定义lastEnd,即上一组的尾结点,指向这一组的开头,即start(如图d节点)。
        while (lastEnd != null) {
            start = lastEnd.next;//start跳到上一组尾结点的next,即这一组的头节点(如图d节点)。
            end = getKGroupEnd(start, k);//组内翻转,end来到这一组的尾结点(如图f节点)。
            if (end == null) {
                return head;//1.什么时候会走这个return?在当前循环的小组中,小组的长度不够k个了,就提前走这个return。
            }
            reverse(start, end);//翻转组内链表
            lastEnd.next = end;//上一组的尾结点的next,指向这一组的尾结点end(如图f节点)。
            lastEnd = start;//lastEnd跳到这一组的头节点(如图d节点)。
            //在每一次循环中,lastEnd的指向,一开始都是不对的,但是在循环的结尾会改对。
        }
        return head;//2.什么时候会走这个return?在链表长度正好是k的整数倍的时候。
    }

    /***
     * 1.
     *      a -> b -> c -> d -> e -> f -> g -> hnull
     *      ^         ^
     *      |         |
     *     head
     *     start      end
     *
     *
     * 2.head来到上一组的尾结点,即c的位置。最后要返回这个head。
     *
     *               head
     *
     *      a -> b -> c -> d -> e -> f -> g -> hnull
     *      ^         ^
     *      |         |
     *     start      end
     */

    /***
     * 组内翻转
     * @param start 组内头节点
     * @param end 组内尾结点
     */
    public static void reverse(ListNode start, ListNode end) {
        end = end.next;//end直接先往下跳一步
        ListNode pre = null;
        ListNode cur = start;
        ListNode next = null;
        while (cur != end) {
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        start.next = end;
    }

    public static ListNode getKGroupEnd(ListNode start, int k) {
        while (--k != 0 && start != null) {
            start = start.next;
        }
        return start;
    }
}
复制代码

 

posted @   TheFloorIsNotTooHot  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程
点击右上角即可分享
微信分享提示