给你链表的头节点 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]
解题方法:(迭代法)
1.首先用for循环统计链表长度,然后设置辅助节点和初始化变量。
-
创建一个哑节点
dummy
,它的next
指向链表头节点head
。这个哑节点简化了处理头节点翻转时的操作。 -
p0
:指向当前需要翻转的k
组的前一个节点。 -
pre
:初始化为null
,用于指向翻转后的子链表的前驱节点。 -
cur
:指向当前处理的节点,初始化为head
。
2.逐组翻转链表。
内层循环翻转当前组节点:
-
保存当前节点的下一节点
nxt = cur.next
。 -
修改当前节点的
next
指针,使其指向前驱节点pre
。 -
将当前节点更新为前驱节点:
pre = cur
。 -
将下一节点更新为当前节点:
cur = nxt
。
更新翻转组的指针:
-
保存当前组的第一个节点(翻转前是
p0.next
):nxt = p0.next
。 -
设置翻转后的最后一个节点的
next
为下一组的第一个节点:p0.next.next = cur
。 -
将
p0.next
指向翻转后的第一个节点:p0.next = pre
。 -
将
p0
更新为下一组的前驱节点(即翻转前的当前组的第一个节点):p0 = nxt
。
/**
* 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 {
public ListNode reverseKGroup(ListNode head, int k) {
int n = 0;
for (ListNode cur = head; cur != null; cur = cur.next) {
n++;
}
ListNode dummy = new ListNode(0, head);
ListNode p0 = dummy;
ListNode pre = null;
ListNode cur = head;
for (; n >= k; n -= k) {
for (int i = 0; i < k; i++) {
ListNode nxt = cur.next;
cur.next = pre;
pre = cur;
cur = nxt;
}
ListNode nxt = p0.next;
p0.next.next = cur;
p0.next = pre;
p0 = nxt;
}
return dummy.next;
}
}