题目:
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
在做这道题之前我们先来研究下单链表的反转。
步骤:
Node * ReverseList(Node *head) { Node *p1,*p2,*p3; if(head==NULL||*head==NULL) return head; p1=head; p2=p1->next; while(p2) //注意条件 { p3=p2->next; //要改变p2->next的指针,所以必须先保留p2->next p2->next=p1; p1=p2; //循环往后 p2=p3; } head->next=NULL; //原先的head已经变成tail,别忘了置空,只有到这步才能置空 *head=p1; return head; }
好了,下面可以开始求解这道题了。
先判断链表的长度是否大于k,如果不是,则返回head,否则,可以递归分解为若干个长度为k的链表,反转后再接起来,用递归进行。
反转方法为上面算法。
#include<iostream> #include <string> #include <stack> #include <vector> using namespace std; struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class Solution1 { public: ListNode* swapPairs(ListNode* head) { if (head == NULL) return NULL; if (head->next == NULL) return head; ListNode *p = head->next; head->next = swapPairs(p->next); p->next = head; return p; } }; class Solution { public: ListNode* reverseKGroup(ListNode* head, int k) { ListNode *p = head; if (p == NULL) return NULL; int i = 0; for (; i < k &&p != NULL; i++) p = p->next; if (i < k ) return head; ListNode *p1, *p2, *p3; p1 = head; p2 = p1->next; for (i = 0; i < k - 1; i++) { p3 = p2->next; p2->next = p1; p1 = p2; p2 = p3; } head->next=reverseKGroup(p2, k); head = p1; return head; } }; int main() { Solution s; ListNode *a1 = new ListNode(1); ListNode *a2 = new ListNode(2); ListNode *a3 = new ListNode(3); ListNode *a4 = new ListNode(4); ListNode *a5 = new ListNode(5); a1->next = a2; a2->next = a3; a3->next = a4; a4->next = a5; ListNode *result = s.reverseKGroup(a1,3); while (result != NULL) { cout << result->val << " "; result = result->next; } cout << endl; return 0; }
长度为k的链表反转的时间复杂度为:O(k)
判断长度是否大于k的时间复杂度为:O(k)
递归次数为(n/k+1)