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;
}
};