BM3题解 | #链表中的节点每k个一组翻转#
链表中的节点每k个一组翻转
https://www.nowcoder.com/practice/b49c3dc907814e9bbfa8437c251b028e
非递归方法
使用四个指针标记一条k链,把这条k链断开、翻转、最后再拼接回去
- 头结点会变,因此使用一个虚拟头结点
- 使用pre和right两个指针用于找到每个k链的起始位置(的前一个节点)和终止位置
- 移动right节点到第k个节点处
- left是pre的后继节点,也是k链的第一个节点;cur是right的后继节点,也就是k链的后继节点
- 断开k链
- 翻转链表
- 翻转后拼接回去就行了,原链表中留了一个pre和一个cur,让pre.next指向翻转后的k链的第一个元素(right)即可,让翻转后的k链的最后一个元素left的next指向原链表中的cur,即可将翻转后的k链拼接回原链表
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) {
if (head == null || head.next == null) return head;
// 头结点会变,因此使用一个虚拟头结点
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
// 这两个指针用于找到每个k链的起始位置(的前一个节点)和终止位置
ListNode pre = dummyHead;
ListNode right = pre;
// 移动right节点到第k个节点处
while (right.next != null){ // 如果right已经是链表的最后一个节点了就不用再找了
for (int i = 0; i < k && right != null; ++i) {
right = right.next;
}
// 如果最后不足k个节点了就直接返回
if (right == null) {
return dummyHead.next;
}
// 用于断开k链的两个指针
ListNode left = pre.next;
ListNode cur = right.next;
// 断开k链
pre.next = null;
right.next = null;
// 翻转链表
reverse(left);
pre.next = right;
left.next = cur;
// 翻转后的链表right为k链第一个节点,left为k链最后一个节点,同时也是下一条k链的前一个节点pre,所以要把pre和right都移动到left的位置,让right在下一个迭代轮次中开始向后移动k位
pre = left;
right = pre;
}
return dummyHead.next;
}
// 翻转链表方法
private void reverse(ListNode head){
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
}
}
查看29道真题和解析