leetcode0025 K个一组翻转链表 - hard

打印 上一主题 下一主题

主题 1849|帖子 1849|积分 5547

1 题目: K个一组翻转链表

官方标定难度:难

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将末了剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要现实进行节点互换。
示例 1:


输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]
示例 2:


输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]
提示:

链表中的节点数目为 n
1 <= k <= n <= 5000
0 <= Node.val <= 1000
进阶:你可以计划一个只用 O(1) 额外内存空间的算法解决此题目吗?

2 solution

如果直接修改指针指向会很贫苦,也很轻易堕落,但是如果先将全部的指针都存储下来,然后按照数组的方式修改就比较简单了。
主要完成以下工作:
1 组内指针方向翻转
2 组间衔接
3 head 修改
4 末了组分环境讨论
代码

  1. ListNode *reverseKGroup(ListNode *head, int k) {
  2.     if(k == 1) return head;
  3.     vector<ListNode *> list;
  4.     ListNode * h = head;
  5.     while (h) {
  6.         list.push_back(h);
  7.         h = h->next;
  8.     }
  9.     if(list.size() < k){
  10.         return head;
  11.     }
  12.     head = list[k - 1];
  13.     int i;
  14.     for (i = 0; i + k - 1 < list.size(); i += k) { // i = 0 2
  15.         // i = 2; j = 3 ->
  16.         for (int j = i + k - 1; j > i; j--) {
  17.             list[j]->next = list[j - 1];
  18.         }
  19.         if (i > 0) // i = 2 [1<-2,3<-4,5]
  20.             list[i - k]->next = list[i + k - 1];
  21.     }
  22.     if(i < list.size()) // i = 4
  23.         list[i - k]->next = list[i];
  24.     else
  25.         list[i - k]->next = nullptr;
  26.     return head;
  27. }
复制代码
结果


3 进阶

你可以计划一个只用 O(1) 额外内存空间的算法解决此题目吗?

这里就不答应我们将全部节点都保存到数组中,只能保存若干个点。我选择保存需要衔接的节点。包括上一组的开始,下一组的开始, 本组的开始,本组的结尾,还有当前节点,上一个节点,下一个节点。
然后按照以下顺序编写。
1 标志好当前组的开头

2 找到当前组的结尾

3 从本组开头一次翻转指向

4 将上一组衔接到本组

5 主要开头在哪

6 结尾特别讨论

  1. ListNode *reverseKGroup(ListNode *head, int k) { // k >= 1
  2.     if (k == 1) return head;
  3.     ListNode *last_head, *cur_head, *cur_tail, *next_head, *last, *now = head, *next;
  4.     int i = 0;
  5.     while (true) {
  6.         i++;
  7.         if (i % k == 0) {
  8.             cur_tail = now;
  9.             next_head = now->next;
  10.             // 翻转
  11.             last = cur_head;
  12.             now = last->next;
  13.             while (now != next_head) {
  14.                 next = now->next;
  15.                 now->next = last;
  16.                 last = now;
  17.                 now = next;
  18.             }
  19.             // 处理尾部
  20.             if (i > k)
  21.                 last_head->next = cur_tail;
  22.             else {
  23.                 head = cur_tail;
  24.             }
  25.             last_head = cur_head;
  26.             now = next_head;
  27.             // cur_head = now;
  28.             i++;
  29.             if (now == nullptr) {
  30.                 cur_head->next = nullptr;
  31.                 return head;
  32.             }
  33.         }
  34.         if (i % k == 1) {
  35.             cur_head = now;
  36.         }
  37.         if (i % k != 0)
  38.             now = now->next;
  39.         if (now == nullptr) {
  40.             last_head->next = cur_head;
  41.             break;
  42.         }
  43.     }
  44.     return head;
  45. }
复制代码
结果



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

没腿的鸟

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表