跳至主要內容

25. K 个一组翻转链表


25. K 个一组翻转链表open in new window

🔴   🔖  递归 链表  🔗 力扣open in new window LeetCodeopen in new window

题目

Given the head of a linked list, reverse the nodes of the list k at a time, and return the modified list.

k is a positive integer and is less than or equal to the length of the linked 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 list's nodes, only nodes themselves may be changed.

Example 1:

Input: head = [1,2,3,4,5], k = 2

Output: [2,1,4,3,5]

Example 2:

Input: head = [1,2,3,4,5], k = 3

Output: [3,2,1,4,5]

Constraints:

  • The number of nodes in the list is n.
  • 1 <= k <= n <= 5000
  • 0 <= Node.val <= 1000

Follow-up: Can you solve the problem in O(1) extra memory space?

题目大意

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。

k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

解题思路

这一题是 第 24 题 的加强版,第 24 题是两两相邻的元素,翻转链表。而本题要求的是 k 个相邻的元素,翻转链表,第 24 题相当于是 k = 2 的特殊情况。

思路一:迭代法

  1. 使用 dummy 作为虚拟头节点,方便处理链表的连接和首节点的反转;
  2. 首先遍历链表,获取链表长度 length,用于判断是否有足够的 k 个节点进行反转;
  3. 每次找到 k 个节点进行反转,通过循环来交换节点的位置,并保持链表正确的连接顺序;
  4. 反转完成后,将指针 prev 移动到下一组的前一个节点,继续遍历下一组 k 个节点,直到剩余节点不足 k

复杂度分析

  • 时间复杂度O(n)
  • 空间复杂度O(1)

思路二:递归法

  1. 判断是否足够 k 个节点:在每次递归之前,遍历前 k 个节点,判断是否有足够的 k 个节点。如果不足 k 个,则直接返回当前链表,不进行反转。
  2. 反转前 k 个节点:通过循环逐个反转 k 个节点。使用 prev 来记录已经反转的部分,curr 用来遍历当前节点,next 记录下一个节点的位置。
  3. 递归处理剩余部分:在反转 k 个节点后,递归处理剩余的链表部分,并将递归结果连接到反转后的链表。
  4. 返回结果:每次递归都返回反转后的链表头节点。

复杂度分析

  • 时间复杂度O(n)
  • 空间复杂度O(n/k),递归方式更加直观,反转过程简洁,但递归栈的深度为 O(n/k)

代码

迭代法
var reverseKGroup = function (head, k) {
	// 创建虚拟头节点,方便处理链表连接
	let dummy = new ListNode(0);
	dummy.next = head;
	let prev = dummy;

	// 统计链表长度
	let length = 0;
	let temp = head;
	while (temp) {
		length++;
		temp = temp.next;
	}

	// 逐步反转每组k个节点
	while (length >= k) {
		let curr = prev.next;
		let next = curr.next;
		for (let i = 1; i < k; i++) {
			curr.next = next.next;
			next.next = prev.next;
			prev.next = next;
			next = curr.next;
		}
		// 移动指针到下一组
		prev = curr;
		length -= k;
	}

	return dummy.next;
};

相关题目

题号标题题解标签难度
24两两交换链表中的节点open in new window[✓]递归 链表
1721交换链表中的节点open in new window链表 双指针
2074反转偶数长度组的节点open in new window链表