25. K个一组翻转链表

迭代

class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {

        ListNode dummyHead = new ListNode(0, head);
        ListNode prev = dummyHead;
        ListNode end = dummyHead;

        /**
         * 设置两个指针,最终要指向每个k区间的头尾,其中end指针不断移动
         * 如果end.next == null,说明链表全部遍历完了
         */
        while (end.next != null) {

            for (int i = 0; i < k && end != null; i++) {
                end = end.next;
            }

            /**
             * 判断剩余节点个数是否大于等于k
             * 如果剩余节点个数小于k,则end == null,直接跳出循环
             */
            if (end == null) {
                break;
            }

            /**
             * 找到一个完整的k区间,进行翻转
             * 保存该区间的头节点和下一个区间的头节点
             * 让该区间的尾节点指向null,然后进行翻转
             */
            ListNode start = prev.next;
            ListNode nextStart = end.next;
            end.next = null;
            prev.next = reverse(start);

            /**
             * 翻转完毕,尾节点变成start,接上下一个区间头节点
             * 同时重置下一个prev和end
             */
            start.next = nextStart;
            prev = start;
            end = prev;
        }

        return dummyHead.next;
    }

    /**
     * 翻转链表
     */
    public ListNode reverse(ListNode head){

        if (head == null || head.next == null){
            return head;
        }

        ListNode next = reverse(head.next);

        head.next.next = head;
        head.next = null;

        return next;
    }
}

/**
 * 时间复杂度 O(n)
 * 空间复杂度 O(1)
 */

递归

class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {

        /**
         * 终止条件
         * 递归过程中head有可能为null。因此也需要判断
         */
        if (head == null || head.next == null || k == 1){
            return head;
        }

        ListNode dummyHead = new ListNode(0, head);
        ListNode prev = dummyHead;
        ListNode next;

        /**
         * 判断剩余节点个数是否大于等于k
         * 如果剩余节点个数小于k,不用翻转直接返回
         * 否则进行递归
         */
        for (int i = 0; i < k && prev != null; i++) {

            prev = prev.next;

            if (prev == null){
                return dummyHead.next;
            }
        }

        next = reverseKGroup(prev.next, k);

        /**
         * 递归以后,只剩下前k个节点需要翻转
         * 翻转以后,最后一个节点是head,和next接上
         */
        prev.next = null;
        ListNode newHead = reverse(head);
        head.next = next;

        return newHead;
    }

    /**
     * 翻转链表
     */
    public ListNode reverse(ListNode head){

        if (head == null || head.next == null){
            return head;
        }

        ListNode next = reverse(head.next);

        head.next.next = head;
        head.next = null;

        return next;
    }
}

/**
 * 时间复杂度 O(n)
 * 空间复杂度 O(n)
 */

https://leetcode-cn.com/problems/reverse-nodes-in-k-group/

posted @ 2021-12-17 14:44  振袖秋枫问红叶  阅读(33)  评论(0)    收藏  举报