「这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战」
题目
给你一个链表,每 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]
示例 3:
输入:head = [1,2,3,4,5], k = 1
输出:[1,2,3,4,5]
示例 4:
输入:head = [1], k = 1
输出:[1]
提示:
- 列表中节点的数量在范围
sz内 1 <= sz <= 50000 <= Node.val <= 10001 <= k <= sz
解题
解题一:分组反转
思路
- 当头节点是 null(head==null),或者一个一组(k==1)时,返回头节点
- 定义
- 结果(result)用于返回翻转后的结果
- 下一个头(nextHead)用于定位下一次翻转头节点
- 临时尾节点(tempTail)用于连接下一个翻转结果
- 循环执行翻转代码,下一个头节点进行遍历
- 如果满足 k 位,则进行翻转,并且加入结果,临时尾节点后移等于下一个头节点
- 如果不满足 k 位,则返回结果
代码
/**
* Definition for singly-linked list.
*/
public class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
class Solution {
/**
* 指定头节点翻转多少位
* @param head
* @param k
* @return
*/
public static ListNode changeHead(ListNode head, int k) {
ListNode nextHead = head.next;
ListNode tail = head;
for (int i = 0; i < k - 1; i++) {
tail.next = nextHead.next;
nextHead.next = head;
head = nextHead;
nextHead = tail.next;
}
return head;
}
public static ListNode reverseKGroup(ListNode head, int k) {
if (head == null || k == 1) {
return head;
}
ListNode result = null;
ListNode nextHead = head;
ListNode tempTail = head;
while (true) {
for (int i = 0; i < k; i++) {
// 遍历列表是否足够 k 个一组
if (nextHead != null) {
nextHead = nextHead.next;
} else {
// 不够一组
if (result == null) {
return head;
} else {
return result;
}
}
}
ListNode reverseNode = changeHead(head, k);
if (result == null) {
result = reverseNode;
} else {
tempTail.next = reverseNode;
tempTail = head;
}
head = nextHead;
}
}
}
总结
性能分析
- 执行耗时:0 ms,击败了 100.00% 的 Java 用户
- 内存消耗:41.4 MB,击败了 5.03% 的 Java 用户