题目链接:
25. K 个一组翻转链表 - 力扣(LeetCode)https://leetcode.cn/problems/reverse-nodes-in-k-group/description/
题目:
给你链表的头节点 head
,每 k
个节点一组进行翻转,请你返回修改后的链表。
k
是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k
的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
例:
例1:
输入:
head = [1,2,3,4,5], k = 2
输出:首先
[2,1,4,3,5]
例2:
输入:
head = [1,2,3,4,5], k = 3
输出:
[3,2,1,4,5]
提示:
- 链表中的节点数目为
n
1 <= k <= n <= 5000
0 <= Node.val <= 1000
思路:
这是LeetCode一道困难题。
首先读题,题目要求没k个链表节点就翻转一次,当剩下的节点数量少于k时,不做任何处理。
因为每次翻转链表后,第一个链表节点一定是翻转后k个链表的尾节点,所以定义一个链表指针tail指向head(即第一个需要翻转的链表节点)。
在翻转中,我们可以每次都将最后一个链表翻转至第一个,但是每次翻转后,由于是单向链表,所以无法找到前一个链表节点的地址。所以我们使用一个vector(变长数组)来存储k个链表节点的地址。在存储链表的过程中,若当前节点指向了NULL,意味着到了最后一个节点,此时若变长数组中节点数量不足k个时,直接返回头结点即可。满足则继续下一步。
接下来为了保护下一个k组能成功翻转,使用一个next指针指向翻转前最后一个链表的下一个链表。
接下来对变长数组中的k个节点进行处理,让最后一个节点成为k个节点翻转后的头结点,然后按照数组中的逆序进行连接链表,然后让最后一个节点指向下一次函数返回的头结点。
最后返回当前k组节点翻转后的头结点即可。
AC代码:
struct ListNode {int val;ListNode* next;ListNode() : val(0), next(nullptr) {}ListNode(int x) : val(x), next(nullptr) {}ListNode(int x, ListNode* next) : val(x), next(next) {}
};class Solution {
public:ListNode* resereve(ListNode* head, int k) {if (head == nullptr || k == 0) {return head;}vector<ListNode*> arr;ListNode* tail = head;for (int i = 1; i < k; i++) {arr.push_back(tail);tail = tail->next;if (tail == nullptr) {return head;}}arr.push_back(tail);ListNode* next = tail->next;ListNode* last;int now = arr.size() - 2;while (now >= 0) {arr[now]->next = tail->next;tail->next = arr[now];tail = tail->next;now--;}tail->next = resereve(next, k);return arr[k - 1];}ListNode* reverseKGroup(ListNode* head, int k) {return resereve(head, k);}
};
如果我的文章对你有所帮助,不妨给我个关注何点赞吧。