LeetCode第 25 题:K 个一组翻转链表(C++)

25. K 个一组翻转链表 - 力扣(LeetCode)

反转链表的进阶版:LeetCode第 206 题:反转链表(C++)_qq_32523711的博客-CSDN博客

链表操作的关键点在于现场保护,本题反转区间之前、之后的节点需要在反转之后连接到正确的位置。翻转是简单的部分,难点在于现场保护和恢复。

可以迭代求解也可以递归求解:

  • 迭代的话,一次遍历就可以获取节点总个数n,n/k即为需要翻转的次数,每次翻转k个节点,需要让k-1个指针反向
  • 递归的话,同样需要操作n/k次,定义函数reverse(node, k)将节点node之后(不包括node)的k个节点进行翻转(难点还是现场的维护),返回翻转后的链表头结点(建议使用dummy节点简化操作),不过单独写函数reverse(node, k)的好处是,每一次传入的k值都可以不同

尽量画图辅助理解:

在这里插入图片描述

迭代法

调了蛮久终于一次提交通过

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        if(!head || !head->next || k == 1)    return head;
        auto dummy = new ListNode(-1);
        int n = 0;
        auto cur = head;;
        while(cur){
            ++n;cur = cur->next;
        }// n 为节点总个数
        cur = head->next;
        auto pre = head;
        auto bef_beg = dummy;
        for(int i = 0; i < n/k; ++i){//每次反转k个,共反转n/k次
            auto beg = pre;
            for(int j = 0; j < k-1; ++j){//k个节点一组,翻转的话只需让k-1个指针反向
                auto p = cur->next;
                cur->next = pre;
                pre = cur;
                cur = p;
            }
            bef_beg->next = pre;
            beg->next = cur;

            bef_beg = beg;
            pre = cur;
            if(cur) cur = cur->next; //此时cur可能为空
        }
        return dummy->next;
    }
};

递归法

思路还是和上面一样的,参数可以是首尾节点,也可以是首节点加上k。

此处采取的思路是传入首前尾后两个节点,具体看代码吧:

reverse函数具体是这样的:

class Solution {
public:
    ListNode* reverse(ListNode *bef_beg, ListNode *after_end){//首前,尾后
        ListNode* pre = bef_beg->next, *beg = pre;//翻转之后返回beg节点
        ListNode* cur = pre->next;
        pre->next = after_end;
        while(cur != after_end){
            auto tmp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = tmp;
        }
        bef_beg->next = pre;
        return beg;
    }
    ListNode* reverseKGroup(ListNode* head, int k) {
        if(!head || !head->next || k == 1)    return head;
        auto dummy = new ListNode(-1);
        dummy->next = head;
        auto bef_beg = dummy;
        while(bef_beg){
            auto end = bef_beg;
            for(int i = 0; i < k; ++i){
                end = end->next;
                if(!end)    return dummy->next;
            }
            bef_beg = reverse(bef_beg, end->next);
        } 
        return dummy->next;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_32523711/article/details/107773840