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:
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个节点的链表反转,然后将反转后的链表接起来,时间复杂度较高
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
void reverse(ListNode* &first, ListNode* &last)
{
ListNode* tail = first;
ListNode* p_next = first;
ListNode* p = first->next;
while(p)
{
first = p;
p = p->next;
first->next = p_next;
p_next = first;
}
last = tail;
}
ListNode* reverseKGroup(ListNode* head, int k) {
if(head == NULL) return NULL;
if(k < 2) return head;
int knode;
ListNode* Head = new ListNode(0,head);
ListNode* plist = Head;
ListNode* prev = Head;
ListNode* first,*last;
while(plist->next)
{
first = plist->next;
last = first;
knode = k -1;
while(knode && last){
last = last->next;
knode--;
}
if(last == NULL){
prev->next = first;
return Head->next;
}
plist = last;
reverse(first,last);
prev->next = last;
prev = first;
}
return Head->next;
}
};
方法二:迭代法,原理如下图
1. 在一个for循环里k个节点里,prev和cur是不移动的,将nex插入prev后面,同时将nex从cur后删除,然后重新将nex指向cur后,tmp指向nex后
2. 下一个k个节点,需要prev指向cur,cur指向prev的后继,nex指向cur的后继,开始循环
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode* pHead = new ListNode(0,head);
ListNode* cur = pHead;
ListNode* prev=pHead,*p_next,*tmp;
int num = 0;
while(cur->next) //cur->next != NULL
{
cur = cur->next;
num++;
}
while(num >= k)
{
cur = prev->next;
p_next = cur->next;
for(int i = 1; i < k;i++)
{
tmp = p_next->next;
p_next->next = prev->next;
prev->next = p_next;
cur->next = tmp;
p_next = cur->next;
}
prev = cur;
num = num - k;
}
return pHead->next;
}
};