考察的知识点:与链表有关的题基本都是插入,删除,交换顺序等,解决这些问题通常将链表的指针进行修改。
问题分析: 这道题需要改变头结点,所以新建一个头结点,然后需要翻转单链表,翻转单链表可以用链表头插, 将需要翻转的结点一个一个头插到某个结点的后面,总之,这道题用头插不是很容易。下面代码看看就行,别细看。
本题解析所用的编程语言:c++
代码如下:
int isreverse(ListNode*& tmp, int& k) //判断是否翻转 { int n = 0; while (tmp) { ++n; if (n == k) { if (tmp->next == nullptr) //因为如果最后一个结点头插,最后一个结点的指针将头插到前一个,此时tmp后面就不为空,所以这里附空 { tmp = nullptr; } return 1; } tmp = tmp->next; } return 0; } ListNode* reverseKGroup(ListNode* head, int k) { // write code here ListNode* newhead = new ListNode(-1); newhead->next = head; ListNode* prev = newhead; //prev是开始进行翻转的前一个结点 ListNode* end = prev->next; //end是每次头插第一个结点 //头插k个结点 ListNode* cur = prev->next; //当前节点 ListNode* next = cur->next; //下一个结点 while (cur) { ListNode* tmp = cur; //tmp进行遍历 if (isreverse(tmp, k)) //够翻转,进行翻转 { for (int i = 0; i < k; ++i) { if (i == 0) { end = cur; } //头插 cur->next = prev->next; prev->next = cur; //更新结点 cur = next; if (cur->next) next = next->next; } //连接结点 prev = end; end->next = cur; } else break; if (tmp == nullptr) //如果全部翻转,将最后一个结点指空,end是每次头插第一个结点,也就是最后一个结点 { end->next = nullptr; break; } } head = newhead->next; delete(newhead); return head; }