题解 | #链表中的节点每k个一组翻转#

链表中的节点每k个一组翻转

https://www.nowcoder.com/practice/b49c3dc907814e9bbfa8437c251b028e

/**
 * struct ListNode {
 *  int val;
 *  struct ListNode *next;
 *  ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
  public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param head ListNode类
     * @param k int整型
     * @return ListNode类
     */
    ListNode* reverseKGroup(ListNode* head, int k) {
        // write code here
        if (head == nullptr || head->next == nullptr) {
            return head;
        }

        if (k < 1 || k > 2000) {
            return nullptr;
        } else if (k == 1) {
            return head;
        } else {
            // 对于链表的操作,先创建一个头节点,避免对head操作产生麻烦
            ListNode* preHead = new ListNode(-1);
            preHead->next = head;

            // 几个指针
            ListNode* preGroupK = preHead;  // 上一组的第k个节点
            ListNode* groupI = preGroupK->next; // 当前组被前插的节点
            ListNode* groupInsert = groupI->next; // 当前组待取下前插的节点

            // 从 1 到 n
            while (preGroupK->next != nullptr) {

                int i;
                for (i = 1; i < k && groupInsert != nullptr; i++) {
                    //取下、前插
                    groupI->next = groupInsert->next;
                    preGroupK->next = groupInsert;
                    groupInsert->next = head;

                    //更新指针
                    groupInsert = groupI->next;
                    head = preGroupK->next; //head始终指向每组的头节点
                } //end for i

                if (i == k) { // 当前组的个数满足k
                    preGroupK = groupI; //指向当前组的第k个节点
                    if (preGroupK->next != nullptr) {   //  强调不是最后一个节点
                        groupI = preGroupK->next; //指向下一个组的被前插的节点
                        head = preGroupK->next;    // 始终指向下一个组的头节点
                        groupInsert = groupI->next; //指向下一组待取下前插的节点
                    } 

                } else {    // 当前组的个数不满足k
                    // 重新前插,将顺序调转回来
                    // 先将指针重新指向
                    groupI = preGroupK->next;
                    head = preGroupK->next;
                    groupInsert = groupI->next;

                    //前插
                    while (groupInsert != nullptr) {
                        // 取下、前插
                        groupI->next = groupInsert->next;
                        preGroupK->next = groupInsert;
                        groupInsert->next = head;

                        // 更新指针
                        groupInsert = groupI->next;
                        head = preGroupK->next;
                    } // end while groupInsert

                    preGroupK = groupI; //指向当前组的最后一个
                } // end else i
            } //end while preGroup->next

            return preHead->next;

        }
        return head;
    } //
};

全部评论

相关推荐

菜菜咪:1. 可以使用简历网站的模版,美观度会更好一点 2. 邮箱可以重新申请一个,或者用qq邮箱的别名,部分hr可能会不喜欢数字邮箱 3. 项目经历最好分点描述,类似的项目很多,可以参考一下别人怎么写的 4. 自我评价可加可不加,技术岗更看重技术。最后,加油,优秀士兵
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务