方法一 模拟法 将一条链表分块分为链表长度/k块链表,如果处不尽则说明后面会有剩下的那一块是不满长度为k的。在最初的时候需要定义两个NodeList表示res(结果)和 now(当前所到达的结果链表的位置)。之后遍历块的长度,对每一个链表块进行翻转,再翻转完后将完成的链表插入到now链表的下一个,再将now链表更新到最前即可。
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if(k <= 1)return head;
if(head == nullptr)return head;
ListNode* node = head;
int len = lenListnode(head);
head = node;
int n = len / k;
ListNode* res = new ListNode(0);
ListNode* cur = res;
for(int i = 0; i < n; i++){
ListNode* temp = nullptr;
for(int j = 0; j < k; j++){
ListNode* t = head->next;
head->next = temp;
temp = head;
head = t;
}
cur->next = temp;
while(cur->next != nullptr)cur = cur->next;
}
cur->next = head;
return res->next;
}
int lenListnode(ListNode* head){
int len = 0;
while(head != nullptr){
head = head->next;
len++;
}
return len;
}
};
方法二 栈
和方法一一样将链表分成每段长度为k的子链表,将每个链表存入栈中,当栈中有k个元素即可一一取出,之后按取出的顺序重组链表就是这一段中翻转的链表,要注意的是处理尾部不满长度为k的链表块时直接取栈底的元素做为最后一段即可。
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if(k <= 1)return head;
if(head == nullptr)return head;
stack<ListNode*>stk;
ListNode* res = new ListNode(0);
ListNode* now = res;
int cnt = 0;
while(true){
for(int i = 0; i < k; i++){
stk.push(head);
head = head->next;
cnt++;
if(head == nullptr)break;
}
if(cnt == k){
while(!stk.empty()){
now->next = stk.top();
stk.pop();
now = now->next;
now->next = nullptr;
}
}
if(head == nullptr)break;
cnt = 0;
}
ListNode* end = nullptr;
while(!stk.empty()){
end = stk.top();
stk.pop();
}
now->next = end;
return res->next;
}
};
|