LeetCode25 K个一组翻转链表
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例:
给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
思路比较简单,现在前面设置一个dummyhead,然后连续翻转长度为k的子链表,注意子链表和头尾的链接。
这里采用的比较复杂的方法,一次传入了4个参数:
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 if (head == nullptr) 13 return nullptr; 14 if (k < 2) 15 return head; 16 ListNode* dummyhead = new ListNode(-1); 17 dummyhead->next = head; 18 ListNode* phead = head, * pbefore = dummyhead, * pafter = nullptr, * ptail = nullptr; 19 int count = 0; 20 ListNode* cur = head; 21 while (cur != nullptr) { 22 ++count; 23 if (count == k) { 24 ptail = cur; 25 pafter = ptail->next; 26 reverse_list(pbefore, phead, ptail, pafter); 27 pbefore = phead; 28 phead = pafter; 29 count = 0; 30 cur = phead; 31 } 32 else { 33 cur = cur->next; 34 } 35 } 36 return dummyhead->next; 37 } 38 39 void reverse_list(ListNode* before, ListNode* head, ListNode* tail, ListNode* after) { 40 ListNode* cur = head, * save = head->next, * last = after; 41 before->next = tail; 42 while (cur != after) { 43 cur->next = last; 44 last = cur; 45 cur = save; 46 if(cur!=nullptr) 47 save = cur->next; 48 } 49 return ; 50 } 51 };
答案给的很简单,使用了pair返回新的头和尾
1 class Solution { 2 public: 3 // 翻转一个子链表,并且返回新的头与尾 4 pair<ListNode*, ListNode*> myReverse(ListNode* head, ListNode* tail) { 5 ListNode* prev = tail->next; 6 ListNode* p = head; 7 while (prev != tail) { 8 ListNode* nex = p->next; 9 p->next = prev; 10 prev = p; 11 p = nex; 12 } 13 return {tail, head}; 14 } 15 16 ListNode* reverseKGroup(ListNode* head, int k) { 17 ListNode* hair = new ListNode(0); 18 hair->next = head; 19 ListNode* pre = hair; 20 21 while (head) { 22 ListNode* tail = pre; 23 // 查看剩余部分长度是否大于等于 k 24 for (int i = 0; i < k; ++i) { 25 tail = tail->next; 26 if (!tail) { 27 return hair->next; 28 } 29 } 30 ListNode* nex = tail->next; 31 // 这里是 C++17 的写法,也可以写成 32 // pair<ListNode*, ListNode*> result = myReverse(head, tail); 33 // head = result.first; 34 // tail = result.second; 35 tie(head, tail) = myReverse(head, tail); 36 // 把子链表重新接回原链表 37 pre->next = head; 38 tail->next = nex; 39 pre = tail; 40 head = tail->next; 41 } 42 43 return hair->next; 44 } 45 }; 46 47 作者:LeetCode-Solution 48 链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group/solution/k-ge-yi-zu-fan-zhuan-lian-biao-by-leetcode-solutio/ 49 来源:力扣(LeetCode) 50 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
又自己写了一版,感觉不如人家的简介,而且条件判断也不如答案简单。
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 if(head==nullptr) return head; 13 ListNode* begin=head,*end=head,*dummyhead=new ListNode(-1),*prevptr=dummyhead; 14 dummyhead->next=head; 15 int curlen=1; 16 ListNode* partialhead,*partialtail; 17 while(end!=nullptr && end->next!=nullptr){ 18 while(curlen<k && end->next!=nullptr){ 19 end=end->next; 20 ++curlen; 21 } 22 if(curlen<k) break; 23 ListNode* nextptr=end->next; 24 pair<ListNode*, ListNode*> result=reverse_partial(begin,end); 25 partialhead=result.first; 26 partialtail=result.second; 27 prevptr->next=partialhead; 28 partialtail->next=nextptr; 29 prevptr=partialtail; 30 begin=nextptr; 31 end=nextptr; 32 curlen=1; 33 } 34 return dummyhead->next; 35 } 36 37 pair<ListNode*,ListNode*> reverse_partial(ListNode* head, ListNode* tail){ 38 if(head==tail) 39 return {tail, head}; 40 ListNode* cur=head->next, *prev=head; 41 while(cur!=nullptr){ 42 ListNode* temp=cur->next; 43 cur->next=prev; 44 if(cur==tail) 45 break; 46 prev=cur; 47 cur=temp; 48 } 49 return {tail, head}; 50 } 51 52 };