给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解:
首先实现链表反转函数。然后没找到k个节点,进行反转。
参考代码:
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode* reverseKGroup(ListNode* head, int k) { 12 //特殊情况:NULL或仅有一个节点 13 if(head == nullptr || head->next == nullptr) 14 return head; 15 16 //虚拟头结点 17 ListNode *dummyHead = new ListNode(0); 18 dummyHead->next = head; 19 20 //next指向当前结点的下一个结点 21 ListNode *next = head; 22 //pre_tail指向上一段链表的尾节点,初始值为空指针 23 ListNode *pre_tail = nullptr; 24 //每一个段的头结点 25 ListNode *newHead = head; 26 //计数值,当count增加到k时,就断链,倒置,挂链 27 int count = 0; 28 29 while(head){ 30 count++; 31 next = head->next; 32 if(count == k){ 33 //断链,并且将该小段链表送入倒置函数中 34 head->next = nullptr; 35 HeadTail headTail = reverse(newHead); 36 37 //挂链:处理倒置后的链表的头和尾,巧妙利用pre初始值是否为空 38 if(pre_tail) 39 //不为空,则上一段链表尾节点指向新置链表头结点 40 pre_tail->next = headTail.head; 41 else 42 //为空,则虚拟头结点指向新置链表头结点 43 dummyHead->next = headTail.head; 44 45 headTail.tail->next = next; 46 47 //更新上一段链表的尾节点、下一段链表的头结点和计数值count 48 pre_tail = headTail.tail; 49 newHead = next; 50 count = 0;//别忘记计数值重置 51 } 52 53 head = next; 54 } 55 return dummyHead->next;//dummyHead大法好 56 } 57 58 //链表的头和尾结构体 59 struct HeadTail{ 60 ListNode *head; 61 ListNode *tail; 62 }; 63 64 //reverse函数返回两个参数:倒置后的链表头和尾 65 HeadTail reverse(ListNode* head){ 66 //巧妙使用pre指针,初始值为空 67 ListNode *pre = nullptr; 68 ListNode *cur = head; 69 ListNode *next = head; 70 while(cur){ 71 next = cur->next; 72 //pre初始值为空 73 cur->next = pre; 74 //更新pre值,很巧妙 75 pre = cur; 76 cur = next; 77 } 78 HeadTail headTail; 79 headTail.head = pre; 80 headTail.tail = head; 81 82 return headTail; 83 } 84 };