每日算法——leetcode系列
问题 Reverse Nodes in k-Group
Difficulty: Hard
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
You may not alter the values in the nodes, only nodes itself may be changed.
Only constant memory is allowed.
For 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
/**
* 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) {
}
};
翻译
k个一组反转节点
难度系数:困难
给定一个链表,每次反转k个节点并返回反转后的链表。
如果节点的个数不是k的倍数,节点后面剩下的部分就不用反转。
不能改变节点的值, 只能改变节点的位置
只允许常数级的内存分配。
例如:
给定链表: 1->2->3->4->5
当 k = 2时, 结果应为: 2->1->4->3->5
当 k = 3时, 结果应为: 3->2->1->4->5
思路
此题分三步分析比较容易理解:
怎么来反转含k个节点的链表?
怎么来反转含n个节点的前k(n >= k)个节点?
怎么k个一组反转含n(n >= k)个节点的链表?
上一个题用next代表下一个节点,当next->next这种情况感觉不友好,现用n代表下一个节点
假设: p代表上一个节点,c代表当前节点,n代表下一个节点
第一个问题,主要就是让c->next = p,方法如下图
第二个问题比第一个问题多了一小点东西,就是以前的头节点要指向第k+1个节点
第三个问题,就是反复调第一个问题,就要是保证每次反转的链表节点个数为k,先让一个节点走到第k个节点,再把这个节点作为尾节点
代码
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if (head == nullptr || head->next == nullptr || k < 2){
return head;
}
ListNode dummy(-1);
dummy.next = head;
ListNode* p = &dummy;
while(p != nullptr){
p->next = reverse(p->next, k);
for(int i=0; p && i<k; i++){
p = p->next;
}
}
return dummy.next;
}
private:
ListNode* reverse(ListNode* head, int k){
ListNode* tail = head;
for (int i = 1; i < k && tail != nullptr; ++i){
tail = tail->next;
}
if (tail == nullptr){
// 节点个数小于k, 这部分不反转
return head;
}
ListNode* p = head;
ListNode* c =p->next;
ListNode* tailNext = tail->next;
while (true) {
ListNode* cNext = c->next;
c->next = p;
if (p == head){
p->next = tailNext;
}
p = c;
if (c == tail){
break;
}
c = cNext;
}
return tail;
}
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。