算法练习- K个一组反转链表

116 阅读1分钟

题目如标题,难点在于如果链表剩余节点少于K个则不反转。

踩坑

如果不判断余下节点个数,是万万做不到滴,因此时间复杂度最低为O(2n)O(2n) -> O(n)

绝妙的思路

递归:终止边界就是链表不足K个,否则反转K个节点,并把反转后的尾部节点后序继续继续反转。

如果按照模拟的思路做,那就是n个K次循环,但是按照递归,不需要管K次循环到底重复几次,一直往后推即可。

实现

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverse(ListNode* begin, ListNode* end) {
        ListNode* pre = nullptr;
        ListNode* cur = begin;
        ListNode* next = nullptr;
        while (cur != end) {
            next = cur->next;
            cur->next = pre;

            pre = cur;
            cur = next;
        }
        return pre;
    }

    ListNode* reverseKGroup(ListNode* head, int k) {
        int i = 0;
        ListNode* pTail = head;
        ListNode* pNode = head;
        for (int i = 0; i < k; i++) {
            if (!pNode) { return head; }
            pNode = pNode->next;
        }
        ListNode* pGroup = reverse(head, pNode);
        pTail->next = reverseKGroup(pNode, k);
        return pGroup;
    }
};