当前位置:   article > 正文

C语言力扣第25题之k个一组反转链表。多指针遍历_力扣题目c语言多层指针

力扣题目c语言多层指针

给你链表的头节点 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) 额外内存空间的算法解决此问题吗?

来源:力扣(LeetCode)
链接:https ://leetcode.cn/problems/reverse-nodes-in-k-group
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

链表分区为已翻转部分+待翻转部分+未翻转部分
每次翻转前,要确定翻转链表的范围,这个必须通过 k 此循环来确定
需记录翻转链表前驱和后继,方便翻转完成后把已翻转部分和未翻转部分连接起来
初始需要两个变量 pre 和 end,pre 代表待翻转链表的前驱,end 代表待翻转链表的末尾
经过k此循环,end 到达末尾,记录待翻转链表的后继 next = end.next
翻转链表,然后将三部分链表连接起来,然后重置 pre 和 end 指针,然后进入下一次循环
特殊情况,当翻转部分长度不足 k 时,在定位 end 完成后,end==null,已经到达末尾,说明题目已完成,直接返回即可

实际上本题就是多次反转整个链表,反转整个链表请参考本人另一篇博客C语言力扣第206题之反转链表。双指针法,迭代递归(三种方法)。图文保姆教程_管二狗绝不摆烂的博客-CSDN博客

  1. struct ListNode* reverseKGroup(struct ListNode* head, int k){
  2. struct ListNode *dummy = malloc(sizeof(struct ListNode));
  3. dummy->next = head;
  4. struct ListNode *node = head;
  5. struct ListNode *sectionNext = NULL,*tail = NULL;
  6. struct ListNode *sectionPrev = dummy;
  7. int actualLength = 0;
  8. while(node != NULL){
  9. actualLength = 0;
  10. /*1. 统计k个长度的node,tail指向该段的结尾,node出当前段,指向下一个段落*/
  11. while(node != NULL && actualLength<k){
  12. tail = node;
  13. node = node->next;
  14. actualLength++;
  15. }
  16. sectionNext = node; //下一段指向段落
  17. if(actualLength==k){ //说明当前是长度达到k 出的循环 ,不用关系node是不是为空,node是下一个段的开始,只要长度达到了就可以反转 ,开始反转
  18. struct ListNode *prev = NULL,*next = NULL; //经典的3指针反转
  19. node = sectionPrev->next; //node 回到当前段的开头
  20. tail = node; //同时tail 也要回来
  21. prev = sectionNext; //prev 指向下一段的开头,链表反转之后尾巴指向下一段开头
  22. while(sectionNext != node){ //while循环条件 node 还没偏移到下一段开头
  23. /*prev curnode next 三指针反转法*/
  24. next = node->next;
  25. node->next = prev;
  26. prev = node;
  27. node = next;
  28. }
  29. /*反转成功之后,prev就是 当前段的链表头*/
  30. sectionPrev->next = prev; //前一段的next指向当前段的链表头
  31. }
  32. /*下一个循环*/
  33. sectionPrev = tail; //sectionprev指向当前段的尾巴,作为下一段的前置节点
  34. node = sectionNext; //node 指向下一段的开始
  35. }
  36. return dummy->next; //返回哨兵节点
  37. }

另外以下这种方式过不了力扣一直显示访问空指针,但可以过VS

  1. struct ListNode* reverseKGroup(struct ListNode* head, int k)
  2. {
  3. struct ListNode* tail = head;
  4. struct ListNode* cur = NULL;
  5. struct ListNode* pre = head;
  6. struct ListNode* head1 = NULL;
  7. struct ListNode* head2 = head;
  8. int i = 0;
  9. for (i = 0; i < k-1; i++)
  10. {
  11. if (tail->next == NULL)
  12. return head;
  13. tail = tail->next;
  14. }
  15. head1 = tail;
  16. while (1)
  17. {
  18. head2 = head;
  19. for (i = 0; i < k-2; i++)
  20. {
  21. head = head->next;
  22. cur = head->next;
  23. head->next = pre;
  24. pre = head;
  25. }
  26. head = cur;
  27. if(tail->next==NULL)
  28. {
  29. head->next = pre;
  30. head2->next = NULL;
  31. return head;
  32. }
  33. else
  34. {
  35. cur = tail->next;
  36. if (pre == NULL)
  37. return;
  38. head->next = pre;
  39. head = cur;
  40. pre = head;
  41. tail = head;
  42. }
  43. for (i = 0; i < k-1; i++)
  44. {
  45. if (tail->next == NULL)
  46. break;
  47. tail = tail->next;
  48. }
  49. if (i != k - 1)
  50. {
  51. head2->next = cur;
  52. break;
  53. }
  54. else
  55. head2->next = tail;
  56. }
  57. head = head1;
  58. return head;
  59. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/87005
推荐阅读
相关标签
  

闽ICP备14008679号