1、题目描述
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
- 你的算法只能使用常数的额外空间。
- 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
2、解题思路
(1)遍历原链表,同时建立一条新链表,分别用newHead和newTail表示头尾指针;
(2)遍历原链表时,每K个为一组,反转后放在前面处理过的链表后面(即插入到newTail节点后面,实现代码中为了代码简洁使用了stack暂存节点。
(3)为了方便操作,我们新建一个新的节点作为辅助头结点。
3、AC代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode* p = head, *newHead = new ListNode(0);
ListNode *newTail = newHead, *tmp = NULL;//newHead为辅助头结点
stack<ListNode*> s;//用栈存储每组的链表节点
while (p)
{
tmp = p;
p = p->next;
tmp->next = NULL;
s.push(tmp);
if(s.size() == k)
{//当栈存够K个节点(刚好一组)的时候,依次出栈按尾插法将出栈节点放在newTail后面
while (!s.empty())
{
newTail->next = s.top();
s.pop();
newTail = newTail->next;
}
}
}
if(s.size() != 0)
{//考虑最后不够K个节点,那么则用头插法将栈中的节点连接起来放在newTail后面,保证原有顺序
ListNode* remainHead = NULL;
while (!s.empty())
{
tmp = s.top();
s.pop();
tmp->next = remainHead;
remainHead = tmp;
}
newTail->next = remainHead;
}
ListNode* res = newHead->next;
delete newHead;
return res;
}
};