给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
/* 把原链表分成若干小段,然后分别对其进行翻转, 那么肯定总共需要两个函数,一个是用来分段的, 一个是用来翻转的,我们就以题目中给的例子来看, 对于给定链表 1->2->3->4->5,一般在处理链表问题时, 我们大多时候都会在开头再加一个 dummy node, 因为翻转链表时头结点可能会变化,为了记录当前最新的头结点的位置而引入的 dummy node, 那么我们加入 dummy node 后的链表变为 - 1->1->2->3->4->5,如果k为3的话, 我们的目标是将 1, 2, 3 翻转一下,那么我们需要一些指针,pre 和 next 分别指向要翻转的链表的前后的位置, 然后翻转后 pre 的位置更新到如下新的位置: - 1->1->2->3->4->5 | | | pre cur next - 1->3->2->1->4->5 | | | cur pre next */ #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vector> using namespace std; struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class Solution { public: ListNode* reverseKGroup(ListNode* head, int k) { if (!head || k == 1) return head; ListNode *dummy = new ListNode(-1), *pre = dummy, *cur = head; dummy->next = head; for (int i = 1; cur; ++i) { if (i % k == 0) { pre = reverseOneGroup(pre, cur->next); cur = pre->next; } else { cur = cur->next; } } return dummy->next; } ListNode* reverseOneGroup(ListNode* pre, ListNode* next) { ListNode *last = pre->next, *cur = last->next; while (cur != next) { last->next = cur->next; cur->next = pre->next; pre->next = cur; cur = last->next; } return last; } }; ListNode* CreateListNode(int arr[], int n) { ListNode* head; head = new ListNode(arr[0]); ListNode* cur; cur = head; for (int i = 1; i < n; i++) { cur->next = new ListNode(arr[i]); cur = cur->next; } return head; } int main() { int k; cin >> k; int n; cin >> n; int i; int a[100]; for (i = 0; i < n; i++) { scanf("%d", &a[i]); } ListNode* head = CreateListNode(a, n); ListNode* result = Solution().reverseKGroup(head,k); while (result != NULL) { printf("%d ", result->val); result = result->next; } system("pause"); return 0; }