题解 | #链表中的节点每k个一组翻转#
链表中的节点每k个一组翻转
https://www.nowcoder.com/practice/b49c3dc907814e9bbfa8437c251b028e
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
public ListNode reverseKGroup (ListNode head, int k) {
// write code here
if (head == null || head.next == null || k == 1) {
return head;
}
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode prev = dummy;
ListNode end = dummy;
while (end.next != null) {
for (int i = 0; i < k && end != null; i++) {
end = end.next;
}
if (end == null) {
break;
}
ListNode start = prev.next;
ListNode next = end.next;
end.next = null;
prev.next = reverse(start);
start.next = next;
prev = start;
end = prev;
}
return dummy.next;
}
private ListNode reverse(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
}
首先,我们创建一个虚拟头结点dummy,将其next指针指向原始链表的头部。然后,我们定义两个指针prev和end,初始时都指向dummy。
在每一轮迭代中,我们先将end指针向后移动k个位置,找到每个翻转子链表的结束位置。如果end为空,说明剩余节点不足k个,退出循环。
然后,我们使用指针start和next来翻转每个子链表。我们将start指向的节点的next指针指向next指向的节点,并同时更新start和next的位置,迭代直到完成翻转。
在翻转子链表时,我们使用了一个辅助指针prev来记录当前节点的前一个节点。初始时,prev为null。我们使用三个指针prev、curr和next来完成链表节点的翻转。
最后,在完成翻转后,我们将每个翻转子链表的前一个节点prev的next指针指向翻转子链表的头部,将翻转子链表的尾部的next指针指向下一个翻转子链表的头部。
最终,返回虚拟头结点dummy的next作为翻转后的链表头部。
时间复杂度为O(n),其中n是链表的长度。空间复杂度为O(1),因为只使用了常数级的额外空间。
查看11道真题和解析