赞
踩
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例 :
- 给定这个链表:1->2->3->4->5
-
- 当 k = 2 时,应当返回: 2->1->4->3->5
-
- 当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
这里的思路是把整个链表分成 K 个结点一组的小链表,然后依次翻转每个小链表,再将这些小链表连起来就是答案。
为了实现这个目标,首先需要一个翻转链表的函数 reverse(),函数返回翻转后的链表,这个是比较简单的。
接下来,我们要把原始链表分成 K 个结点一组的小链表去翻转。
这里用 cnt 计数,ans 为最终翻转后的链表的头指针,p 为最终翻转后的链表的尾指针,temp 指向当前小链表的头结点,head 指向当前结点。
当 cnt+1 == K 时,说明从 temp 至 head 总共有 K 个结点,这个时候应该把这个小链表拿出来翻转一下然后接到 p 的后面。用 end 指向当前 head 指向的结点。令 end = NULL,就把小链表从原始链表上拿下来了。p->next = reverse(temp) 就把翻转后的小链表接到了当前已经翻转的链表的后面。再用一个 while 循环,把 p 更新为当前已经翻转的链表的尾指针。接下来开始找下一个小链表,首先更新 head = head->next,因为 temp 存储的是下一个小链表的头结点,所以要令 temp = head,这样又回到了初始状态,所以要 continue 跳过本次循环后面的内容;当 cnt + 1 ≠ K 时,head = head->next 即可。
最后还应有 p->next = temp,因为当最后一组结点没有 K 个时,是不会翻转的,但 temp 仍指向最后一组结点的头结点,直接把 temp 接到 p 后面即可。
参考代码如下:
- class Solution {
- public:
- ListNode* reverse(ListNode* head) {
- ListNode* ans = NULL;
- while(head) {
- ListNode* next = head->next;
- head->next = ans;
- ans = head;
- head = next;
- }
- return ans;
- }
- ListNode* reverseKGroup(ListNode* head, int k) {
- int cnt = 0;
- ListNode* ans = new ListNode(0);
- ListNode* temp = head, *p = ans;
- while(head) {
- cnt++;
- if(cnt == k) {
- cnt = 0;
- ListNode* end = head;
- head = head->next;
- end->next = NULL;
- p->next = reverse(temp);
- while(p->next)
- p = p->next;
- temp = head;
- continue;
- }
- head = head->next;
- }
- p->next = temp;
- return ans->next;
- }
- };
这题周末想了好久都没搞出来,今天状态好,一会儿就做出来了,看来状态好的时候效率真的会很高呀,以后要尽量在状态好的时候做一些有难度的事情。
加油。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。