题目
LeetCode: Reverse Nodes in k-Group
给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。
示例:
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
思路
这虽然是个困难题,感觉还没中等题难。
思路也比较简单,先翻转k个节点,翻转之前先判断一下是否有k个节点,如果没有k个节点,就不翻转。
翻转之后将原来的尾结点也就是新的头结点记录下来,在翻转下一组的时候链上之前一组的头结点即可。
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool JudgeNodeNum(struct ListNode* cur, int k)
{
//得判断一下长度够不够翻转
while (k--)
{
if (cur == NULL)
{
return false;
}
cur = cur->next;
}
return true;
}
struct ListNode* reverseKGroup(struct ListNode* head, int k) {
struct ListNode *prev = NULL, *cur = head, *next = NULL;
struct ListNode* ret = head;
struct ListNode *cur_end = NULL, *prev_end = NULL;
int count = k;
if (head == NULL || k == 1)
{
//翻转k为1或者为空,直接返回
return ret;
}
while (JudgeNodeNum(cur, k) == true)
{
count = k;
prev_end = cur_end;//记录前一部分的尾结点
cur_end = cur;//记录当前尾结点
while (count--)
{
//翻转当前部分的k个节点
next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
}
if (ret == head)
{
//ret为返回的头结点
ret = prev;
}
if (prev_end != NULL)
{
//如果前一个部分的k个节点的尾不为第一部分的尾
//链接两个部分
prev_end->next = prev;
}
prev = NULL;
}
if (cur_end != NULL)
{
//链接剩余部分
cur_end->next = cur;
}
return ret;
}