25. K 个一组翻转链表

223 阅读1分钟

「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战」。

题目描述

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

k 是一个正整数,它的值小于或等于链表的长度。

如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

进阶:

你可以设计一个只使用常数额外空间的算法来解决此问题吗? 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

示例 1:

输入: head = [1,2,3,4,5], k = 2
输出: [2,1,4,3,5]

思路分析

在做过翻转链表以后,这道题就不算困难了,至少思路上很容易理解。

  • 先判断是否需要翻转:剩余长度是否大于等于k
  • 对接下来k个节点进行翻转
  • 循环上面两步

为了方便起见,我们将第二步操作和第一步操作提取出来

pair<ListNode*, ListNode*> reverseK(ListNode* node, ListNode* tail){
        ListNode* tmp = node;
        ListNode* pre = tail -> next;
        while(tmp != tail){
            ListNode* tt = tmp -> next;
            tmp -> next = pre;
            pre = tmp;
            tmp = tt;
        }
        tmp -> next = pre;
        return {tail, node};
    }
 bool isNeed(ListNode* node, int k){
        ListNode* tmp = node;
        for(int i = 0; i < k; i ++){
            if (tmp != nullptr){
                tmp = tmp -> next;
            }else{
                return false;
            }
        }
        return
 }

实操的时候打的代码有很多问题,经过排查后其实是对于翻转后的一组节点,没有将它连到整个长链路中。导致会出现节点的缺失。

具体实现

ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* node = head;
        ListNode* hair = nullptr;
        ListNode* pre = hair;
        ListNode* ret =nullptr;
        bool flag = true;
        while(isNeed(node, k)){
            ListNode* nex = getKNode(node, k);
            // cout << node->val << endl;
            ListNode* wei = getK1Node(node, k);
            tie(node, wei) = reverseK(node, wei);
            //  cout << pre  << endl;
            if(flag){
                ret = node;flag = false;
            } 
            if (pre != nullptr){
                
                pre ->next = node;
            }
            wei -> next = nex;
            node = wei -> next;  
            // cout << pre  << " " << wei->val<< endl;
            pre = wei; 
            // cout << pre->val  << " " << wei->val<< endl;

        }
        return ret;
    }