25. K 个一组翻转链表
给你链表的头节点 head
,每 k
个节点一组进行翻转,请你返回修改后的链表。
k
是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k
的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
//抄的
class Solution {
public:ListNode* reverseKGroup(ListNode* head, int k) {if (!head || k == 1) return head;ListNode dummy(0);dummy.next = head;ListNode* prev_tail = &dummy;while (true) {ListNode* check = prev_tail->next;for (int i = 0; i < k; i++) {if (!check) return dummy.next; // 不足 K 个,直接返回check = check->next;}// 反转当前 K 个节点ListNode* curr_head = prev_tail->next;ListNode* prev = nullptr;ListNode* curr = curr_head;for (int i = 0; i < k; i++) {ListNode* next = curr->next;curr->next = prev;prev = curr;curr = next;}// 连接已反转部分prev_tail->next = prev; // 上一组的尾指向当前组的新头curr_head->next = curr; // 当前组的新尾指向剩余部分prev_tail = curr_head; // 更新 prev_tail 为当前组的尾}}
};
处理太复杂了,难搞
逻辑先判断剩余节点是否足够,不够就直接返回保存的返回节点。如果足够,反转下面k个节点。反转结束,需要链接反转后的头到上一轮的尾,反转后的尾继续往后指。
不难得出,需要实时维护两个个指针,指向上一轮的尾和当前轮的旧头,这样才能避免链表断裂。
代码就是按上面的逻辑逐步实现的,下面对指针含义进行简要说明
dummy,虚头节点,可以视为第0轮反转后保存的尾部,dummy.next将指向第一轮反转后的头部
prev_tail,维护的前一轮反转后的尾部,开始即dummy,后面会实时变化
check,检测剩余节点个数的指针
curr_head,当前轮反转前的头,反转后的尾,最后赋值给prev_tail
prev,curr,next,正常反转就用到的指针,反转结束后,prev指向新头,curr指向下一轮