1、 用栈分组翻转。单次翻转,时间复杂度o(n),空间复杂度o(k)。
#include<stack>
using namespace std;
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
stack<ListNode *> stk;
ListNode dummy = ListNode(0);
dummy.next = head;
// 哨兵节点
ListNode *pre = &dummy;
while(head != nullptr) {
int i = 0;
for(i=0; i<k && head!=nullptr; i++) {
stk.push(head);
head = head->next;
}
if (i==k) {
pre->next = stk.top();
stk.pop();
ListNode * cur = pre->next;
while(!stk.empty()) {
cur->next = stk.top();
stk.pop();
cur = cur->next;
}
pre = cur;
// 这里把已翻转区间的右节点和未翻转的左节点连接,让区间不足的情况不用处理
pre->next = head;
} else {
while(!stk.empty()) {
stk.pop();
}
}
}
return dummy.next;
}
};
2、复用翻转链表前n个节点的能力(实现方法:递归)。每次分组翻转前,有前置的哑节点做定位,调用翻转链表前n个节点的函数,再拼接哑节点和翻转后的链表。时间复杂度o(n),空间复杂度o(k)
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
ListNode* reverseKGroup(ListNode* head, int k) {
if(k<=1 || head == nullptr) {
return head;
}
int n = 0;
ListNode* cur = head;
while(cur != nullptr) {
n++;
cur = cur->next;
}
ListNode dummy = ListNode(0);
dummy.next = head;
ListNode *pre = &dummy;
while(n>=k) {
n -= k;
cur = pre->next;
ListNode* newHead = reverseNLength(cur, k);
pre->next = newHead;
pre = cur;
}
return dummy.next;
}
ListNode* reverseNLength(ListNode* head, int n) {
if(n<=1 || head == nullptr) {
return head;
}
ListNode* next = head->next;
ListNode* newHead = reverseNLength(next, n-1);
head->next = next->next;
next->next = head;
return newHead;
}
};
- 复用翻转链表前n个节点的能力(实现方法: 头插法)。增加一个哑节点作为定位。时间复杂度o(n),空间复杂度o(1)
#include<stack>
using namespace std;
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
ListNode* reverseKGroup(ListNode* head, int k) {
stack<ListNode *> stk;
ListNode dummy = ListNode(0);
dummy.next = head;
// 哨兵节点
ListNode *pre = &dummy;
while(head != nullptr) {
int i = 0;
for(i=0; i<k && head!=nullptr; i++) {
stk.push(head);
head = head->next;
}
if (i==k) {
while(!stk.empty()) {
ListNode *top = stk.top();
stk.pop();
pre->next = top;
pre = top;
}
// 翻转末尾将下一个区间的起始连起来,最后一段不需要翻转的情况就无需处理
pre->next = head;
} else {
while(!stk.empty()) {
stk.pop();
}
}
}
return dummy.next;
}
};

京公网安备 11010502036488号