当前位置:   article > 正文

链表反转之K个一组反转_c 语言编程 给你一个链表,每k个节点一组进行翻转

c 语言编程 给你一个链表,每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]
在这里插入图片描述

1. 头插法

思路: 将链表根据 k 的值进行分组, 再分别对每一组进行反转。

在这里插入图片描述
代码实现:

/**
 * 头插法
 *
 * @param head
 * @param k
 * @return
 */
public static ListNode reverseKGroup2(ListNode head, int k) {
    ListNode dummyNode = new ListNode(-1);
    dummyNode.next = head;
    ListNode curr = head;
    // 计算链表长度
    int len = 0;
    while (curr != null) {
        len++;
        curr = curr.next;
    }
    // 根据 k的值进行分组
    int n = len / k;
    ListNode pre = dummyNode;
    curr = head;
    // 分组进行反转
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < k - 1; j++) {
            ListNode next = curr.next;
            curr.next = curr.next.next;
            next.next = pre.next;
            pre.next = next;
        }
        // 准备进入下一组反转
        pre = curr;
        curr = curr.next;
    }
    return dummyNode.next;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

2. 穿针引线法

思路: 将链表分组处理, 将其分为已经反转、正在反转、未反转三个部分。遍历链表, 根据 k 的值找到四个关键位置, 分别代表已经反转部分的尾结点、正在反转部分的头节点、正在反转部分的尾结点以及未反转部分的头节点, 使用变量 pre、start、end和next标记。

在这里插入图片描述

对待反转的部分进行反转:

在这里插入图片描述

调整指针位置, 进行下一组反转:

在这里插入图片描述

代码实现:

/**
 * 穿针引线法
 *
 * @param head
 * @param k
 * @return
 */
public static ListNode reverseKGroup(ListNode head, int k) {
    ListNode dummyNode = new ListNode(-1);
    dummyNode.next = head;
    ListNode pre = dummyNode;
    ListNode end = dummyNode;
    while (end.next != null) {
        // 先找到待反转链表部分的尾节点
        for (int i = 0; i < k && end != null; i++) {
            end = end.next;
        }
        if (end == null) {
            // 当最后一组待反转链表长度小于k, 不满足要求时, 退出循环
            break;
        }
        // 待反转链表部分的头节点
        ListNode start = pre.next;
        // 未反转 (下一组) 部分链表头节点
        ListNode next = end.next;
        end.next = null;
        pre.next = reverse(start);
        start.next = next;
        pre = start;
        end = pre;
    }
    return dummyNode.next;
}

private static ListNode reverse(ListNode head) {
    ListNode pre = null;
    ListNode curr = head;
    while (curr != null) {
        ListNode next = curr.next;
        curr.next = pre;
        pre = curr;
        curr = next;
    }
    return pre;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/86947
推荐阅读
相关标签
  

闽ICP备14008679号