用yummyhead的非递归方法,先获取每组元素,如果够k个元素就反转。反转通过头插法来实现。

class Solution {
public:
/*
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
ListNode
reverseKGroup(ListNode* head, int k) {
// write code here
// 每k个一组,进行反转

    if (k == 0 || k == 1) return head;
    ListNode *yummyhead = new ListNode(-1);  // 设置伪头结点保证循环操作的一致性
    yummyhead->next = head;
    ListNode *p = yummyhead, *q = nullptr, *cur = yummyhead;  // cur指向每一段的最后一个结点
    while (cur->next) {
        int i = 0;

        for (; i < k && cur->next; i++) {  // 虽然只有一个元素,但还是够跳两次
            cur = cur->next;  // 循环退出时,cur指向第k个位置才可啊,以上两种表达结果是一样的,都是先next在++
            // 跳k-1下,得到长度为k的链表
        }  // 循环后,cur指向的该组的最后一个结点

        if (i == k) {
            // 说明该组够k个元素,则反转
            q = cur->next;  // 让后继指针指向后继节点,防止断链
            cur->next = nullptr;  // 让该组的最后一个结点和后续结点断链,用于后续的反转链表操作

        // 反转前需要记录子链表的第一个结点,反转后该结点将成为子链表的尾结点,与后边链表链接
            ListNode *tmp = p->next;
            // 反转
            p->next = reverse(p->next);  // 将子链表反转,并将上一组组尾元素指向他
            p = tmp;
            tmp->next = q;
            cur = tmp;
        }

    }

    return yummyhead->next;

}

ListNode* reverse(ListNode *head) {
    // 实参指针是复制来了的副本
    // 用头插法实现反转,即遍历链表的每一结点,将其插入到新链表的表头
    ListNode *yummyhead = new ListNode(-1);
    // ListNode *cur = yummyhead->next;
    ListNode *tmp = nullptr;
    while(head) {
        tmp = head->next;  // 记录后续结点,防止断链
        head->next = yummyhead->next;  // 在这里正好将头插的第一个结点的next置空
        yummyhead->next = head;
        head = tmp;  // 相当于遍历指针后移
    }
    return yummyhead->next;
}

};