题目链接

K 个一组翻转链表

题目描述

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

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

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

示例:
image.png

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

说明:

  • 你的算法只能使用常数的额外空间。
  • 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

    解题思路

    1. 双指针 + 模拟

    1. class Solution {
    2. public ListNode reverseKGroup(ListNode head, int k) {
    3. ListNode dummy = new ListNode(-1);
    4. ListNode pre = dummy;
    5. ListNode start = head;
    6. ListNode end = head;
    7. while (end != null) {
    8. // 当节点总数不是 k 的整数倍时,最后剩余的节点就不足 k 个
    9. // 因此 end 会走到 null。这里要判断 end 防止空指针
    10. for (int i = 1; i < k && end != null; i++) {
    11. end = end.next;
    12. }
    13. // end 为 null 就说明剩余节点不足 k 个
    14. // 直接跳出循环,保留剩余节点的原有顺序
    15. if (end == null) {
    16. break;
    17. }
    18. ListNode temp = end.next;
    19. end.next = null;
    20. pre.next = reverse(start);
    21. start.next = temp;
    22. pre = start;
    23. start = temp;
    24. end = temp;
    25. }
    26. return dummy.next;
    27. }
    28. public ListNode reverse(ListNode head) {
    29. ListNode pre = null;
    30. while (head != null) {
    31. ListNode temp = head.next;
    32. head.next = pre;
    33. pre = head;
    34. head = temp;
    35. }
    36. return pre;
    37. }
    38. }
  • 时间复杂度LeetCode25. K 个一组反转链表 - 图2

  • 空间复杂度LeetCode25. K 个一组反转链表 - 图3

    2. 递归

    class Solution {
      public ListNode reverseKGroup(ListNode head, int k) {
          ListNode l1 = head;
          ListNode l2 = head;
          for (int i = 0; i < k; i++) {
              // 递归出口:如果剩余节点不足 k 个,不进行反转,保持原顺序
              if (l2 == null) {
                  return l1;
              }
              l2 = l2.next;
          }
          ListNode res = reverse(l1, l2);
          l1.next = reverseKGroup(l2, k);
          return res;
      }
      // 对 list1 - list2 区间中的节点进行反转
      public ListNode reverse(ListNode list1, ListNode list2) {
          ListNode pre = null;
          while (list1 != list2) {
              ListNode temp = list1.next;
              list1.next = pre;
              pre = list1;
              list1 = temp;
          }
          return pre;
      }
    }