力扣刷题:6-K 个一组翻转链表(25)

123 阅读1分钟

对链表按每k个节点为一组,进行翻转,其实就是对整个链表先翻转前k个节点,然后将翻转过的节点的下一个节点作为新的头节点,继续翻转前k个节点,直到没有节点或剩余不到k个节点。

下面是C语言实现的代码,每一次循环进行一次前n个节点的翻转,然后获取下一个节点作为下次循环的头节点,其中,翻转的过程利用了递归函数。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

struct ListNode* __reverseN(struct ListNode* head, int n) {
    if (n == 1) {
        return head;
    }
    struct ListNode* tail = head->next;
    struct ListNode* p = __reverseN(head->next, n - 1);
    head->next = tail->next;
    tail->next = head;
    return p;
}

struct ListNode* reverseN(struct ListNode* head, int n) {
    struct ListNode* p = head;
    int cnt = n;
    while (--cnt && p) {
        p = p->next;
    }
    if (p == NULL) {
        return head;
    }
    return __reverseN(head, n);
}

struct ListNode* reverseKGroup(struct ListNode* head, int k) {
    struct ListNode ret = {
        .val = 0,
        .next = head
    };
    struct ListNode* prev = &ret;
    struct ListNode* next = prev->next;
    while ((prev->next = reverseN(next, k)) != next) {
        prev = next;
        next = prev->next;
    }
    return ret.next;
}