Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
You may not alter the values in the nodes, only nodes itself may be changed.
Only constant memory is allowed.
For example,
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
我的AC(8ms,落后8.5%,击败5%)(起一个有意义的变量名是多么的重要=。=):
(此法未用dummy,因为讨论了是否为第一组数,dummy法在 Leetcode ☞ 203. Remove Linked List Elements ☆ 【dummy 方法二重点掌握】里介绍,此题也可用哒,懒得写了~)
struct ListNode* reverseKGroup(struct ListNode* head, int k) { if (!head || !head->next || k == 1) return head; struct ListNode *curr = head; struct ListNode *thisTurnStart = head; struct ListNode *prevTurnLast = NULL; struct ListNode *p; int count = k - 1, lens = 0, turn; for(p = head; p ; p = p->next, lens++); turn = lens / k;//有几组数需要反转 while(turn--){ while(count--){//注意的是count=k-1。例:k=2时,只操作一次。k=3时,操作两次。 p = curr->next; curr->next = p->next; p->next = thisTurnStart; thisTurnStart = p; } if(prevTurnLast)//如果第一组数,那么head就确定下来了;如果不是第一组数,要把上一轮最后一个节点跟这轮第一个节点连起来。 prevTurnLast->next = thisTurnStart; else head = thisTurnStart; thisTurnStart = curr->next;//下轮反转中的起点 prevTurnLast = curr;//下轮反转中的 上一组最后一个节点 curr = thisTurnStart; count = k - 1; } return head; }
分成数个小组,分别在组内反转,用到了Leetcode ☞ 206. Reverse Linked List ☆的第二个方法:每次都取出一个点放在第一个节点的前面。
循环时,需讨论是不是第一个小组:是则确定下来return的头节点,否则把上一组的最后一个节点与这组的头节点相连。【dummy法可免去这一步骤~】
二重指针法:
struct ListNode* reverseKGroup(struct ListNode* head, int k) { if (k == 1) return head; size_t len, groups, n; struct ListNode **p, *groupHead, *node; // get list length for (len = 0, node = head; node; node = node->next) len++; // group num groups = (int)(len / k); if (groups == 0) return head; p = &head; while (groups--) { if (*p) { groupHead = *p; node = groupHead->next; } n = k - 1; // n node to be reversed in a group while (n--) { groupHead->next = node->next; node->next = *p; *p = node; node = groupHead->next; } p = &groupHead->next; } return head; }