新设一个头结点方便操作,然后用三个指针pre,cur,tmp针对每k个元素进行一次反转,一轮反转之后更新pre为新的cur继续下一轮反转。
而反转的轮数需要根据结点总数来确定,所用先遍历一遍求出总结点数,除以k求出轮数。
struct ListNode* reverseKGroup(struct ListNode* head, int k ) {
    if(head == NULL)
       return NULL;
    if(k == 1)
       return head;
    struct ListNode* result = malloc(sizeof(struct ListNode));
    result->next = head;
    struct ListNode *pre, *cur, *tmp;
    pre = result, cur = head, tmp = NULL;
    int len = 0;
    while(head != NULL){
        len++;
        head = head->next;
    }
    int groups = len / k;
    for(int i = 0; i < groups; i++){
        for(int j = 1; j < k; j++){
            tmp = cur->next;
            cur->next = tmp->next;
            tmp->next = pre->next;
            pre->next = tmp;
        }
        pre = cur;
        cur = cur->next;
    }
    return result->next;

上面的头插法是拆一个接一个,一直保持链表长度不变。
另一种更常规的头插法是新建一个头结点,然后从原链表每k个一反转,然后接入新链表,使新链表一节一节增长。
//第2种
struct ListNode* reverseKGroup(struct ListNode* head, int k ) {
    if(head == NULL)
       return NULL;
    if(k == 1)
       return head;
    struct ListNode* c = head;
    int len = 0;
    while(c != NULL){
        len++;
        c = c->next;
    }
    int groups = len / k;
    struct ListNode* result = malloc(sizeof(struct ListNode));
    result->next = NULL;
    struct ListNode* now;
    now = result;
    struct ListNode* hou;
    for(int i = 0; i < groups; i++){
        struct ListNode* tmp = malloc(sizeof(struct ListNode));
        tmp->next = NULL;
        for(int j = 0; j < k; j++){
            hou = head->next;
            head->next = tmp->next;
            tmp->next = head;
            head = hou;
        }
        now->next = tmp->next;
        while(now->next != NULL)
            now = now->next;
    }
    now->next = head;
    return result->next;
}