25. K 个一组翻转链表
25. K 个一组翻转链表
题目描述
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
进阶:
你可以设计一个只使用常数额外空间的算法来解决此问题吗?
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。提示:
- 列表中节点的数量在范围
sz内1 <= sz <= 50000 <= Node.val <= 10001 <= k <= sz
思路分析
链表的问题其实很套路,最好在纸上或者脑海里想一想,要理清思路。对于本体,K个一组反转链表,那么就把链表分为K组,对于每个组,设定两个指针,一个指针head指向本组的开头,一个指针end指向本组的末尾,然后对本组进行翻转即可。对于每个组反转之后,还要把每个组连起来,那么再设定一个指针pre保存前一组的尾巴,然后连起来即可。对于第一组是个特殊情况,pre没有指向,那么就创造一个虚拟节点。
代码实现
/**
* 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* reverseKGroup(ListNode* head, int k) {
//增加一个虚设头节点
ListNode* hair=new ListNode();
hair->next=head;
//pre指向上一组的末尾,初始化指向hari
ListNode* pre=hair;
//end用于指向每组的末尾(反转前是末尾,反转后是开头)
ListNode* end=hair;
while(end!=nullptr)
{
//首先让end找到末尾
for(int i=0;i<k&&end!=nullptr;i++) end=end->next;
//如果末尾为空,表示这一组少于k个,因此不用反转
if(end==nullptr) break;
//让上一组的末尾指向本组的开头(反转后end就是开头)
pre->next=end;
//更新pre指向本组反转后的末尾
pre=head;
//对本组进行翻转
while(head!=end)
{
ListNode* tmp=head->next;
head->next=end->next;
end->next=head;
head=tmp;
}
//更新
end=pre;
head=end->next;
}
return hair->next;
}
};

浙公网安备 33010602011771号