题目:
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
例子:
Example 1:
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
Note:
- Only constant extra memory is allowed.
- You may not alter the values in the list’s nodes, only nodes itself may be changed.
问题解析:
给定单向链表,以k个节点作为一组进行链表的翻转。如果剩下的节点不满k个,则不进行翻转。
链接:
思路标签
分步进行:先统计,后翻转
解答:
- 题目其实不难,关键是理清楚翻转的操作,以及所需要的节点;
- 首先统计后面的节点是否满足k个作为一组进行翻转,若不满足则不进行翻转;
- 注意每次都需要记录前一个翻转组的最后一个节点,进而与下一组的翻链表进行连接;
- 注意,返回的链表的头节点是记录第一组翻转后的头节点,与后面的无关,或者如果没有一组进行过翻转,则直接返回原始链表头节点。
/** * 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) {
if (k == 1 || head == nullptr)
return head;
ListNode *pHead = head;
ListNode *pNode = head;
ListNode *pTailPrevious = pNode;
int first = true;
while(pNode != nullptr){
ListNode *pTail = pNode;
int n = 1;
// 统计后面是否还存在k个节点
while(pNode != nullptr && n <= k){
pNode = pNode->next;
n++;
}
// 如果还存在k个节点则进行翻转并对该k个节点翻转链表与之前的进行连接,否则不进行翻转直接连接。
if(n > k){
pNode = pTail;
ListNode *pPrevious = nullptr;
n = 1;
while(n <= k){
ListNode *pNext = pNode->next;
pNode->next = pPrevious;
pPrevious = pNode;
pNode = pNext;
n++;
}
// 判断是否是第一段,第一段的翻转节点为最后的头节点
if(first == true){
pHead = pPrevious;
pTailPrevious = pTail;
first = false;
}else{
pTailPrevious->next = pPrevious;
pTailPrevious = pTail;
}
}else{
// 如果还是第一段则说明不足k个,直接返回链表
if(first == true){
return pHead;
}
pTailPrevious->next = pTail;
}
}
return pHead;
}
};