LeetCode 25 K 个一组翻转链表 | Java 刷题打卡

274 阅读2分钟

本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接

题目描述

K 个一组翻转链表

给你一个链表,每 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]

示例 3:

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

示例 4:

输入:head = [1], k = 1
输出:[1]

提示

  • 列表中节点的数量在范围 sz
  • 1 <= sz <= 5000
  • 0 <= Node.val <= 1000
  • 1 <= k <= sz

思路分析

一开始解答这道题的时候,我试图对每 k 个进行反转,记录下 k+1 的指针,但是我们没有对 k.next 置为 null,这样在反转的时候处理很是复杂,后面看了一些优秀的解法,及时对 k.next 置为 null,最后再进行衔接,一下子方便很多了。

代码展示

链表的反转是个必须掌握的点,反转 k 个节点的时间复杂度是O(n){O(n)},空间复杂度是O(1){O(1)}

public ListNode reverseKGroup(ListNode head, int k) { //1,2 ,3,4, 5
        ListNode dummy = new ListNode();
        dummy.next = head;
        ListNode start = dummy;
        ListNode end = dummy;
        while (end.next != null) { //end != null 会再走一下,到下面进行break
            for (int i = 0; i < k; i++) {
                if (end != null) {
                    end = end.next;
                }
            }
            if (end == null){
                break;
            }
            //下一组的头部
            ListNode next = end.next; //3  5
            end.next = null;
            //现在的头部
            ListNode currentHead = start.next; //currentHead = 1   currentHead = 3

            //反转后的头部,currentHead变尾部了
            ListNode reverseHead = reverse(currentHead); //reverseHead = 2,currentHead = 1 reverseHead = 4,currentHead = 3

            start.next = reverseHead; //start.next = 2   start.next = 4
            currentHead.next = next;  //currentHead.next = 3  currentHead.next = 5

            start = currentHead; //start = 1
            end = start; //end 也是要设置一下的,因为 end 原本指向某个地址,但是反转了,这个地址变到前面了

        }
        return dummy.next;
    }
		//链表反转
    private ListNode reverse(ListNode head){
        ListNode prev = null;
        ListNode current = head;
        while (current != null){
            ListNode next = current.next;
            current.next = prev;
            prev = current;
            current = next;
        }
        return prev;
    }

总结

像这样的 k 个一组翻转链表,虽然题意简单,但是真正实现是比较复杂的,很考验编程着对链表的掌握程度。如果按照上面逻辑一步步自己写出来,思路还是比较清晰的,也就是 k 个 k个 进行反转,每 k 个进行反转的时候,把 k+1 的指针保存下来,对 k.next 置为空,处理好衔接。